Made the query-by-example.adoc a top level document. Clients including the documents have to tweak the indentation on the inclusion side then. Included query-by-example.adoc into index.adoc so that it can be double checked in test renderings easily.
Renamed ExampleSpecification to ExampleMatcher and introduced a matching() factory method, dropping the dedicated override mechanism for types for now. Updated documentation accordingly.
Used Lombok for constructor creation, field defaults, toString() as well as equals(…) and hashCode() implementations.
Tweaked imports in unit tests. Renamed methods to express expected behavior.
Original pull request: #153.
Split Example and ExampleSpec to create reusable components. Refactor builder pattern to a fluent API that creates immutable instances. Split user and framework API, Example and ExampleSpec are user API, created ExampleSpecAccessor for modules to access example spec configuration. Create static methods in GenericPropertyMatchers to ease creation of matchers in a readable style. Convert PropertySpecifier to inner class and move PropertySpecifiers to ExampleSpec.
Related tickets: DATAJPA-218, DATAMONGO-1245.
Original pull request: #153.
Added required types for Query by Example which should be used by the individual store implementations.
Generally the Example type captures a sample object and allow various settings concerning the mapping into an actual query. So there’s configuration options for handling null values, string matching, property paths to ignore,
Related tickets: DATAJPA-218, DATAMONGO-1245.
Original pull request: #153.
ResultProcessor.processResult(…) now explicitly handles null values to prevent IllegalArgumentExceptions being provoked in the ProjectionFactory which occurred if null values were handed down to it.
We now resolve composed annotation values using @AliasFor within AnnotationBasedPersistentProperty and BasicPersistentEntity. Nevertheless it is up to the individual store implementation to make use of this.
Original pull request: #156.
Previously, we registered an InstantiationAwareBeanPostProcessor to predict the type to be created by RepositoryFactoryBeanSupport by inspecting a particular property value of the registered BeanDefinition.
This has now been elevated to a more generic mechanism that can get a FactoryBean type configured with a set of properties to inspect for a configured type. That new infrastructure now replaces the explicit configuration for RepositoryFactoryBeanSupport with one that's set up via configuration.
Fixed indentation to use tabs instead of spaces. Tweaked structure of if-clauses in PropertyAccessingMethodInterceptor to reduce nesting. Made helper method static.
Restructured test cases slightly and used ExpectedException rule to verify exceptions. Moved newly introduced test methods more to the end of the file (new tests last).
Added author and copyright year extensions where necessary.
Original pull request: #155.
We now use a non-static cache for TypeInformation instances in SimpleTypeInformationMapper to make sure Spring Boot's development tools can correctly reload classes. Removed the static singleton instance of SimpleTypeInformationMapper in favor instantiating it directly.
Introduced a template method to override the creation of a PagedResource to allow subclasses to create a more concrete instance than PagedResource itself.
The ChainingConverter now returns values as soon as one converter in the chain produces an instance that's compatible to the target type. This allows ResourceProcessor clients to provide a Converter to take care of the complete conversion themselves.
QueryMethods now expose a ResourceProcessor which is exposes information about the final to be created object types which can either be DTOs containing a persistence constructor (see @PersistenceConstructor) or projection interfaces. The former are analyzed for constructor properties so that store implementations can use that information to create projected queries that return exactly the fields required for that DTO.
Projection interfaces are inspected, their properties are considered input properties and the same projection queries can be issued against the data store. If a projection contains dynamically calculated properties (i.e. it uses SpEL expressions via @Value) the original entities have to be queried and can be projected during post processing.
ProjectionFactory now exposes a more advanced ProjectionInformation that has additional meta information about the projection type. ProxyProjectionFactory now refers to the BeanClassLoader instead of the ResourceLoader.
RepositoryFactory(Bean)Support now also implement BeanFactoryAware to forward the BeanFactory to the SpelAwareProxyProjectionFactory which in turn now gets handed into the QueryLookupStrategy as well as the QueryMethod.
Parameter now knows about a dynamic projection type, which is a query method parameter of type Class bound to a generic method parameter and will be used to determine the projection to be used on a per call basis.
Original pull request: #150.
If a single path is now handed to QuerydslBindings.bind(…), a specialized AliasingPathBinder is returned which allows defining an alias the binding will be exposed under.
By default that alias will cause the original binding being black-listed and thus become unavailable for binding. This can be overridden by explicitly white-listing the properties to be bindable.
Switched to new Querydsl 4 artifacts and adapted to changed package names and API changes.
Cleaned up some JavaDoc and APIs in QuerydslBindingsFactory and QuerydslBinderCustomizer.
If the type lookup from the store source returns a raw generic type (e.g. resolving the value of a generic property against a value of that generic type - i.e. not a more concrete type binding the generic information) in the context of a generic property, we previously did not apply the generics information of the contextual instance to that very raw type.
We now expose a TypeInformation.specialize(ClassTypeInformation) which applies the current generics context to the given raw type and basically creates a synthetic parameterized TypeInformation instance.
DefaultTypeMapper applies this specialization by default now with ClassTypeInformation simply returning the given type as is so that we don't create any resolution overhead in case no generics are involved in the first place.
The ProjectingMethodInterceptor now uses a default ConversionService instance to try to convert a potentially not matching result of the target invocation into the type the projection requires before the attempt to create nested projection.
Query method parameter values of JDK 8 or Guava Optional type are now transparently unwrapped on parameter value access. ParametersParameterAccessor now unwraps them on instance creation.
The assignability check of method return types now explicitly detects wrapper types supported in QueryExceutionConverters and automatically unwraps those before the actual check.