Previously we only allowed to sort by QueryDsl path expressions. With this change we now also support ordering by operator expressions, e.g. yearMonth() on a date property.
Original pull request: #94.
The type detection for entity candidates of PersistentProperty instances now consistently handles collection types even if they're used als collection or map values.
Annotations used on both fields and accessors are now only rejected if they're Spring Data annotations (i.e. from the org.springframework.data namespace) and the configurations of these annotations differ.
Renamed CdiRepositoryConfigurationSource to CdiRepositoryConfiguration. Turned anonymous inner default implementation into dedicated enum to avoid repeated instantiation.
Changed the CdiRepositoryBean to rather take a Bean instance of the custom implementation instead of the resolved object to make sure both instances (the custom implementation and the repository proxy) are instantiated at the same time.
Fixed imports. Some early returns to avoid unnecessary nesting.
Adapted architecture description to allow CDI module accessing the configuration module.
Related pull request: #92.
The CDI extension now discovers a custom implementation class similarly to the detection when using Spring Data in a Spring container. Extracted the custom implementation detection for re-use. The CDI extension discovers the potentially available bean and hands it to the CdiRepositoryBean for further usage.
Implementations should implement the extended variant of the create(…) method we introduce with this commit to be able to forward the resolved custom implementation bean.
Original pull request: #92.
We now apply a stricter repository interface selection if we detect multiple Spring Data modules to be in the classpath to avoid the repository scanning accidentally overriding each others definitions or even picking up interfaces they weren't intended to manage.
The detection is based on a type scan in dedicated base package where subtypes of RepositoryFactorySupport usually reside. If more than one type is found, we activate strict scanning.
The strict check is actually implemented in RepositoryConfigurationExtensionSupport to be accessible for store implementations. By default we try to load the repository candidate interface and inspect the managed domain types for a collection of annotations (see RepositoryConfigurationExtensionSupport.getIdentifyingAnnotations()). Implementors still have the chance to customize the behavior by overriding isStrictRepositoryCandidate(…).
We also introduced a getModuleName() to be able to create better logging output in terms of repository registration. Moved registration of RepositoryConfigurationExtension as Spring bean into the base types for XML and annotation configuration support to make sure they only kick in if explicit configuration is used.
PropertyPath now exposes the complete property named the resolution failed for in case it can't resolve a source String. It will expose the part of the Path from the deepest successful resolution result.
Changed the resolution algorithm to use a List instead of a Stack and a fresh instance of the former so that the nested recursion steps keep track of the correct resolution depths.
RepositoryConfigurationDelegate now registers the store-specific RepositoryConfigurationExtension as lazy-init BeanDefinition so that other parties can detect that definition.
We're now firing the component registration event manually in RepositoryBeanDefinitionParser as ParserContext.registerBeanComponent(…) registers the given BeanComponentDefinition with the registry. As we do that manually before this previously resulted in the BeanDefinition overriding the very same one and container warnings in turn.
Refactored the implementation of the dynamic lookup of properties and functions on EvaluationContextExtensions. All the reflective lookup logic has moved into an EvaluationContextExtensionAdapter.
We now also distinguish between the meta-information that can be looked up once and cached (so that we avoid reflection overhead for subsequent context creations).
Related pull request: spring-projects/spring-data-jpa#101
Related ticket: DATAJPA-564
Changed SPI to expose a Function type rather than plain methods as well as an arbitrary root object.
Related pull request: spring-projects/spring-data-jpa#101
Related ticket: DATAJPA-564
Collapsed variable gathering methods into one, make sure we expose all values (also null ones). Renamed unit test for ExtensionAwareEvaluationContextProvider according to the class name. Some further cleanups in the test case.
Related pull request: spring-projects/spring-data-jpa#101
Related ticket: DATAJPA-564
We now expose special parameters like Pageable and Sort to be used in SpEL expressions if they don't collide with existing named parameters.
Related pull request: spring-projects/spring-data-jpa#101
Related ticket: DATAJPA-564
We new automatically register public static fields declared on classes extending EvaluationContextExtensionSupport as properties to be used within SpEL expressions.
Related pull request: spring-projects/spring-data-jpa#101
Related ticket: DATAJPA-564
We new automatically register public static methods declared on classes extending EvaluationContextExtensionSupport as functions to be used within SpEL expressions.
Related pull request: spring-projects/spring-data-jpa#101
Related ticket: DATAJPA-564
Extracted SPI build for DATAJPA-564 into Spring Data Commons. Simplified the configuration setup code and removed the ability to define a custom EvaluationContextProvider for now. We directly declare a bean definition which automatically picks up EvaluationContextExtensions.
RepositoryFactory(Bean)Support is now aware of the EvaluationContextProvider to hand it to the template method that creates the QueryLookupStrategy. Deprecated the previously existing template method in favor of an extended one.
Removed variable declarations from the extension interface for now as usually properties serve the same purposes as variables which makes the latter superfluous for now. Applied some JavaDoc and API signature polish. Added unit tests for ExtensionAwareEvaluationContextProvider.
Related pull request: spring-projects/spring-data-jpa#101
Related ticket: DATAJPA-564
This commit introduces @ReadOnlyProperty to mark properties as not to be persisted. That trait is exposed via the newly added PersistentProperty.isWritable() which supersedes shallBePersisted(). Currently all non-transient property that are not annotated with @ReadOnlyProperty are considered writable.
Original pull request: #88.
DefaultRepositoryInformation now excludes default methods from the query methods it detects. RepositoryFactorySupport adds a special MethodInterceptor to the proxy which handles the invocation of default methods.
Related tickets: DATACMNS-535.
We now synchronize the (seldom) writes to the isPropertyParameterCache HashMap in PreferredConstructor via a ReadWriteLock. We could as well have used a ConcurrentHashMap here without the need for manual locking but this would potentially waste memory for a mostly read-only data structure. We also anticipate potential multiple writes for the same property.
Original pull request: #86.
Parameters erroneously rejected @Param annotated query method parameters that were preceded by a non-bindable type (like Pageable or Sort) as it checked for a 0 index of the parameter. We now manually keep an index in the check itself and have removed the Parameter.isFirst() method as it's not used anywhere else.
We can now detect whether a given query method wants to limit the query results based on two new supported prefixes (findFirstBy…(…) and findFirstKBy…(…)) where "First" part can also be replaced by "Top" and an following optional K (which must be a decimal int) that denotes the maximal number of result rows to be retuned by the query.
This can be used by the stores to allow queries like:
- T findFirstBy…OrderBy…Asc -> smallest
- T findFirstBy…OrderBy…Desc -> greatest
- T findTopBy…OrderBy…Desc -> greatest
- T findFirstBy…(Sort sort) -> general purpose
- T findTopBy…(Sort sort) -> general purpose
- List<T> findFirstKBy…OrderBy…Asc -> smallest K
- List<T> findFirstKBy…OrderBy…Desc -> biggest K
- List<T> findFirstKBy…(Sort sort) -> general purpose TOP K
- List<T> findTopKBy…(Sort sort) -> general purpose TOP K
The limiting expressions also support the Distinct expression. Also, for the queries limiting the result set to one instance, wrapping the result into an Optional is supported.
If pagination or slicing is applied to a limiting query pagination (and the calculation of the number of pages available) is happening within the limited result.
Original pull request: #85.
We're now using the newly introduced method on ControllerLinkBuilderFactory that takes both a type and a method to forward the method the invocation is happening on independently from the method being invoked.
The equals(…) and hashCode() methods of TypeVariableTypeInformation previously tried to evaluate the unresolved context of the type variable. This can cause issues in recursive type definitions as set up in the according test case. We now implement the methods based on the resolved type to makes sure we break the recursive lookup of PersistentEntity instances in AbstractMappingContext.
The erroneous lookup was actually caused by unresolved base types being added to the mapping context within the JPA project as the JPA meta-model also returns those types as managed types.
Related pull request: #84.
As SPR-11744 got fixed recently and will be available in Spring 3.2.9, we removed the guard in RepositoryBeanDefinitionRegistrarSupport which defaulted the environment in case it was not set by the container.
Related tickets: SPR-11744.
In case the repository method execution returns a collection that needs to be converted into a different collection (e.g. List -> Set) we erroneously ran into a NullableWrapper conversion. This was due to the fact that we only used the raw method return type, which caused the ObjectToCollectionConverter to kick in (as the target type's component type falls back to Object if we use raw types).
We're now using Spring's MethodParameter abstraction to create a TypeDescriptor for the method's return type which fully supports generics, so that the conversion check for NullableWrapper -> target type does not match the ObjectToCollectionWrapper.
Prepared the QueryExecutionConverters to be able to support recursive type conversion once we move to Spring 4 as TypeDescriptor exposes the ResolvedType as of this version so that we can inspect the type parameter of the wrapper type to invoke a nested conversion (e.g. Integer -> Optional<String> requires NullableWrapperTo(Guava|Jdk)OptionalConverter being invoked and in turn recursively convert the Integer to String).
We now also reflectively check for the presence of DefaultParameterNameDiscoverer. This allows the usage of the new reflection methods introduced in Java 8 if the user code is running on Spring 4.
Changed the name of the constant for the ParameterNameDiscoverer in Parameters to meet conventions for constants.
If a configuration class resides in the default package and no base package is defined in the @Enable…Repositories annotation we previously failed in extracting the package from the class name (as there is none).
We now use Spring's ClassUtils that correctly handles this case and returns an empty String for the default package.
Spring 4's GenericTypeResolver returns null when trying to resolve type arguments for types that do not fully resolve the generic types.
Related issues: SPR-11763.
Added a converter to process a NullableWrapper into a Future by producing an AsyncResult. This is to support repository methods annotated with @Async and returning a Future<T>. With Spring's asynchronous method invocation support activated this will cause the repository method being executed asynchronously.
Note, that this currently only works on Spring 4 as Spring 3.2.8 async support is not discovering the introduction on the repository proxy and thus fails to discover the @Async annotation on the repository method. This will be resolved in Spring 3.2.9, see the related tickets.
Related tickets: DATACMNS-483, SPR-11725, DATACMNS-499.
Version parsing failed when given version contained non-numeric parts (like 2.0.0-rc1). We now strip everything after the first non numeric part to create a logical version equivalent of the source String.
Original pull request: #81.
Added a constructor to RepositoryConfigurationDelegate that takes an additional Environment instance to make sure we can equip ClasspathScanningCandidateComponentProviders with Environments to make sure they only find components matching the environment.
Retain the old constructor by defaulting to the Environment the ResourceLoader potentially contains or even a StandardEnvironment in worse cases. This is primarily to not break existing clients. Those should be upgraded to use the new constructor, of course.
Needed to add an additional guard in BeanDefinitionRegistrarSupport as Spring 3.2.8 fails to invoke EnvironmentAware (filed SPR-11744 for that). This should be removed once we upgrade to Spring 3.2.9.
Related pull request: #80.
Related tickets: DATACMNS-493, DATACMNS-494, SPR-11744.
Fixed @since-tags, added author tags where appropriate, fixed copyright header in SortUnitTests. Removed unnecessary formatting line comments. Renamed nullHandlingHint to nullHandling inside Order. Changed builder method signatures to be consistent with with(…) methods defining the direction.
Fixed copy & paste test in SortUnitTests.
Original pull request: #79.
Null handling hints can now be configured on Order as being either NATIVE (we let the data store decide how to order nulls), NULLS_FIRST or NULLS_LAST.
This is the foundation for custom null-handling in other data store support modules like SD JPA and SD MongoDB.
Original pull request: #79.
The repository method invocation mechanism now post-processes the result of the actual method invocation in case it's not type-compatible with the return type of the invoked method and invokes a conversion if applicable. This allows us to register custom converters for well-known wrapper types. We currently support Optional from both Google Guava and JDK 8.
Implementation notice
We use some JDK 8 type stubs from the Spring Data Build project to be able to compile using JDKs < 8. This is necessary as we need to remain compatible with Spring 3.2.x for the Dijkstra release train and our test executions still run into some issues with it a Java 8 runtime (mostly ASM related). These issues were reported in [0, 1] and we'll probably get off the hack for Dijkstra GA by upgrading to Spring 3.2.9.
[0] https://jira.spring.io/browse/SPR-11719
[1] https://jira.spring.io/browse/SPR-11718
The default implementations of the TypeInformation Mapper interfaces now work with ClassTypeInformation where possible to express they only map raw types effectively.
Added TypeInformation.getRawTypeInformation() to easily turn whatever TypeInformation into the raw type representation. Changed ClassTypeInformation.from(…) to return ClassTypeInformations directly.
Previously, ParameterizedTypeInformation.hashCode() had been inconsistent to equals in case of a fully resolved parameterized type. This is now fixed by not including the parent reference in case a parameterized type is resolved completely.
Also, TypeDiscoverer.getActualType() does not return the component type for non-collection/non-maps anymore to make sure we don't accidentally unwrap parameterized types.
Added Serializable marker interface to Shape to make all geospatial types serializable. Changed equals implementation in GeoResults to use equals(…) instead of reference equality.
Original pull request: #77.