We now use RepositoryComposition as backing implementation for repository method calls to implementations. We now scan for repository fragments during the repository configuration phase. Fragment implementation candidates derive from the repository interface declaration, specifically the declared interfaces and their order. We scan the class path during fragment scan for each interface and add discovered fragments to the repository composition. The name of the implementation is derived from the simple name of the interface and the implementation suffix. Qualified fragments are top-level interface declarations that are not annotated with NoRepositoryBean. Inherited interfaces are not considered as fragment candidates.
We create a RepositoryComposition from the discovered fragments in the order of interface declaration in the repository interface and supply the composition to the actual repository creation.
Original pull request: #222.
We now accept Publisher<T> instead of Mono<T> in findById(…) and existsById(…). Users of a ReactiveStreams-based framework are no longer required to perform Publisher to Mono-adoption themselves but can pass a Publisher directly. Both methods use the first emitted value to issue their queries. Additional values are not consumed from the stream.
Original Pull Request: #226
As per @jhoeller's recommendation, we now use the ResourceLoader's ClassLoader instead of the bean ClassLoader exposed by the XmlReaderContext. The latter can apparently be null outside certain lifecycle phases.
Related pull request: #201.
Use Streamable in configuration APIs for more efficient, lazy traversal of source lists. Introduced SelectionSet.of(…) to move away from constructors. Avoid the use of null in SelectionSet.
Original pull request: #201.
When multiple repository implementations are found based on the class name, the one with a bean name matching the interfaces bean name + implementation postfix is picked. Includes support for CDI.
RepositoryBeanNameGenerator now no longer implements BeanNameGenerator since while it produces names it does not behave like the interface suggests, i.e. it can work without a BeanFactory in the first place. It now uses constructor injection and is package private.
Original pull request: #201.
Remove javadoc params without documentation. Reorder methods in the order they are called. Rename arePropertyHashCodesUnique to hasUniquePropertyHashCodes. Add author tag. Formatting.
Original pull request: #224.
Refactored all the checks done to check if ClassGeneratingPropertyAccessorFactory works into separate methods, so the body of isSupported becomes nice and readable.
Original pull request: #224.
ClassGeneratingPropertyAccessorFactory does not work with Java 9 (encapsulated modules, without --permit-illegal-access), because making ClassLoader.defineClass accessible fails.
Therefore this change moves call to setAccessible to the check that ensures availability of the method so isSupported(…) returns false.
Original pull request: #224.
Spring Data 2.0 is going GA after the feature freeze of RxJava 1. In prospect of its EOL it makes no sense to ship new APIs based on a library that goes towards EOL.
RxJava1CrudRepository and RxJava1SortingRepository are subject to removal in a future milestone.
DefaultMethodInvokingMethodInterceptor now contains two alternative implementations, one compatible to Java 8, one for Java 9.
Original pull request: #223.
Update JavaDoc to reflect reactive types, not null arguments and potential exceptions.
Align not null JavaDoc of imperative QueryByExample interface.
Original Pull Request: #197
Provide a mix-in interface to be used in store modules providing reactive Query by Example query execution.
Mono<T> findOne(Example<T> sample);
Flux<T> findAll(Example<T> sample);
Mono<Long> count(Example<T> sample);
//...
Original Pull Request: #197
We now return Optional<T> for QuerydslPredicateExecutor.findOne(Predicate) aligning the return type to the ones used in CrudRepository.
Original pull request: #215.
All overloaded methods are now available in SPeL expressions. Among methods with identical argument list from different sources in the same extension (extension, root object, aliases) the last one in the order in parens wins. If there is more than one method for an application the following rules are applied: if there is one method with exact matching types in the argument list it is used, otherwise an exception is thrown.
Original pull request: #217.
We now eagerly check the accessibility of the defineClass(…) method on the class loader to be used for a PersistentEntity. This will then cause the clients to use a different PropertyAccessorFactory (as things stand today: the one using reflection) and not fail to create the class later on.
Revert change to only invoke cleanup method if events have been exposed. We now again invoke the cleanup method for every aggregate. Changed the publication of events from the aggregate instances that were handed into the method to the ones the save method returns as the save call might return different object instances.
Cleanups in the unit tests. Moved newly introduced methods to the bottom of the test case class. Extracted method to set up mock method invocation.
Original pull request: #216.
We now make sure the event cleanup method is called on the aggregate root, not on the parameter object directly (as the latter might be a collection.
Original pull request: #216.
Replaced optional dependencies with Optional and explicit null checks with calls to ifPresent. Used Lambda style instead of anonymous classes where applicable. Converted Hamcrest matchers to AssertJ.
Minor improvements to formatting.
Original pull request: #208.
Introduced dedicated callback interfaces to customize the HandlerMethodArgumentResolver instances registered by SpringDataWebConfiguration. This allows bean definition registration of those customizer interfaces instead of having to extend a configuration class.
Original pull request: #208.
Previously we explicitly intercepted repository methods named save(…) and saveAll(…) which unfortunately results in custom variants of that (e.g. JpaRepository's saveAndFlush(…)) not causing event publication.
We now publish events for methods whose names start with save….
Introduced ConverterBuilder which exposes API to register Spring GenericConverters for the use with a store module's CustomConversions. This allows simple registration of such converters using Java 8 lambdas.
ConverterAware converters = ConverterBuilder.reading(String.class, Long.class,
it -> Long.valueOf(it)).andWriting(it -> Object::toString);
The setup can also be done from the reading side which would just need the method invocations inverted. The resulting ConverterAware will expose the registered converters so that they can be easily handed to a CustomConversions instance. Partial creation of either reading or writing converters is possible, too with the returned instance then only exposing one of the two converters.
CustomConversions now considers ConverterAware and treats them appropriately for ConvertiblePair registration as well as during the registration in the ConversionService. Tweaked parameter types in CustomConversions to rather accept a Collection<?> for the converters (previously List<?>). Also, registerConverterIn(…) now takes a ConverterRegistry over a GenericConversionService. Polished Javadoc and non-null assertions.
Original pull request: #209.
In case a repository method execution returns a JDK 8 Optional in the first place, the Optional instance had been wrapped into a third-party null-wrapper as is. We're now unwrapping the value held inside that optional and forward it to the value conversion.
We now follow a more consistent naming scheme for the methods in repository that are driven by the following guidelines:
* Methods referring to an identifier now all end on …ById(…).
* Methods taking or returning a collection are named …All(…)
That results in the following renames:
* findOne(…) -> findById(…)
* save(Iterable) -> saveAll(Iterable)
* findAll(Iterable<ID>) -> findAllById(…)
* delete(ID) -> deleteById(ID)
* delete(Iterable<T>) -> deleteAll(Iterable<T>)
* exists() -> existsById(…)
As a side-effect of that, we can now drop the Serializable requirement for identifiers.
Updated CRUD method detection to use the new naming scheme and moved the code to Java 8 streams and Optional. Adapted RepositoryInvoker API to reflect method name changes as well.
We now support Order creation with Order.asc(String) and Order.desc(String) factory methods as shortcut to constructor creation via new Order(Direction, String).
Sort.by(Order.asc("age"), Order.desc("name"));
Deprecated Order(String) constructor in favor of the Order.by(String) factory method. Replace references to new Order(String) with Order.by(String).
Original pull request: #211.