Both the configuration code looking up Spring Data specific Jackson modules as well as the code detecting whether we have multiple Spring Data modules on the classpath used component scanning. That can have quite significant impact on startup times.
This commit replaces the classpath scanning with the use of SpringFactoriesLoader that now requires modules that want to extend the behavior of Spring Data's web configuration or indicate a repository implementation being present by shipping a file called META-INF/spring.factories. Spring Data relies on the following keys:
- org.springframework.data.web.config.SpringDataJacksonModules - list the Spring configuration classes that will expose additional Jackson modules that are supposed to be registered for Spring Data's Jackson web support
- org.springframework.data.repository.core.support.RepositoryFactorySupport - list the Spring Data repository factory implementation class that implements repository support for your module. The general detection and configuration mechanism for user repositories is not affected by this. Currently Spring Data only uses the pure number of different entries for that key to switch into strict configuration mode in case we find more than one entry.
We now publish events for all methods named "save" on the repository. Fundamentally, that's in place to capture calls to CrudRepository.save(Iterable entities), too.
Some minor refactorings to the internal setup of EventPublishingMethodInterceptor. More JavaDoc.
Introduced @DomainEvents usable on a method of an aggregate root. The method will be invoked when the aggregate is passed to a repository to save and its returned value or values will be exposed via an ApplicationEventListener.
Also, the aggregate can expose a method annotated with @AfterDomainEventPublication which will be invoked once all events have been published.
We now try to look up a target class method based on concrete name and parameter type before falling back on the more expensive type matches. This also eliminates the possibility of invalid method matches as described in the ticket.
We now no longer attempt query creation for static methods declared on a repository interface. This allows static method usage inside of repository interfaces.
interface PersonRepository extends CrudRepository<Person, String> {
static String createId() {
// …
}
default Person findPerson() {
return findOne(createId());
}
}
PageableHandlerMethodArgumentResolver.isFallbackPageable() now correctly guards against the fallback Pageable being null, a situation that's explicitly deemed valid in setFallbackPageable(…).
This commit changes some ArrayList initializations to use an initial capacity and avoids the unnecessary fetch of the return type of a method in Parameter.isDynamicProjectionParameter().
Original pull request: #180.
The special case of an Iterable parameter doesn't have to be handled explicitly anymore so that we can simplify the type match check in DefaultRepositoryInformation.
Related ticket: DATACMNS-912.
Previously, ClassGeneratingPropertyAccessorFactory uses boxed types for primitive type setters. This threw NoSuchMethodExceptions and caused ExceptionInInitializerError as the generated class could not be initialized. We now use the appropriate argument type to look up setters.
Also, we now only generate accessor usage if the property is configured to use property access in the first place.
Original pull request: #178.
QueryExecutionResultHandler now explicitly handles null values for query methods returning Maps by returning an empty Map. This can be the case if a query is supposed to produce a Map (a single result) but doesn't actually yield any results at all.
We now correctly check the bounds of generic methods if we deal with a type variable found as method parameter. Introduced different code paths for type and method level generics so that the latter is explicitly checking all bounds available.
After the Spring 5 build profile has been activated properly in Spring Data build [0], the test cases for RepositoryPopulators failed as there was only an explicit detection of Spring 4 to point the test to the right resource file. Removed the guard now as all supported versions can now use the same file.
Adapt to the stricter contract in Spring 5's MethodParameter in unit test for QuerydsPredicateArgumentResolver.
[0] 31df5de907
The proxies created for projections now defensively mask getDecoratedClass(), a method declared on DecoratingProxy, an interface that JDK proxies on Spring 4.3 will implement.
The introduced method allows creating new Order instances for a different property ensuring all other aspects (ignore case, null handling) are retained.
Introduced dedicated RevisionSort property that allows to define the sort order independent of the revision property to be used.
Introduced methods to find out whether a Sort is descending or ascending to avoid having to refer to the enum.
We now support exists projections in derived queries by parsing the exists keyword and expose it via PartTree.isExistsProjection().
Original pull request: #171.
Previously, calls to ParameterizedTypeInformation.getMapValueType() caused an infinite recursion when invoked on a type information that was not a map type. This lead to a StackOverflowError.
We now call the super method doGetMapValueType() instead of calling the entry super method getMapValueType() and return by that null in case the map value type is not resolvable.
Original pull request: #176.
We now provide equals(…) and hashCode() methods for GenericPropertyMatcher, PropertySpecifier and PropertySpecifiers so that they can be compared and used in sets.
Original pull request: #175.
If the same generic type was used on recursively nested generics declarations, like this:
class GenericType<T> {}
class Nested extends GenericType<String> {}
class Concrete extends GenericType<Nested> {}
our traversal of the generics discovered T bound to String in Nested and as that is extending GenericType as well, the T detected here is the same instance as the T within the map discovered for Concrete. As we previously added the nested types after we added the original entry, the nested discovery overwrote the more local one.
We now make sure the detected nested type variable mappings don't overwrite already existing ones.
Changed the implementation of both the JSON Path and XPath based projecting HttpMessageConverters to make sure the cached decisions don't depend on the media type. Reuse the evaluation of the media type in AbstractHttpMessageConverter.