Moved PropertyDescriptor lookup into dedicated subclass to group functionality around the type and MethodsMetadata instances. Extracted individual stream handling steps into dedicated methods for better understandability.
Moved MethodsMetadataReader into classreading package for symmetry with Spring Framework's metadata arrangement. Removed manually declared getters in DefaultMethodsMetadataReader in favor of Lombok getters. Inlined MethodsMetadataReadingVisitor into DefaultMethodsMetadataReader as it's only used there.
Original pull request: #263.
We now provide MethodsMetadataReader to read method metadata from a class file. MethodMetadata is read for all user-declared methods except for constructors (which are technically methods, too).
MethodsMetadataReaderFactory factory = new MethodsMetadataReaderFactory();
MethodsMetadataReader metadataReader = factory.getMetadataReader("com.acme.Foo");
MethodsMetadata metadata = metadataReader.getMethodsMetadata();
This new API is now used by DefaultProjectionInformation to make sure the order of input properties is based on the declaration order in the projection interfaces. Previously that order could not be guaranteed to be stable.
Original pull request: #263.
We now explicitly check for an enum type in SimpleTypeHolder.isSimpleType(…) and resort to true immediately. Before that an enum implementing an interface could have seen a false for the actual enum type in case the interface type had been checked first and (correctly) produced a false. In the check for the actual enum type, depending on the iteration order through the cached values we could've hit the cached false for the interface or the cached true value for Enum.
As a consequence of our renaming efforts in CRUD methods, we lost some generics lookup information to distinguish deleteById(ID) from delete(T) solely based on the method parameter type in case of an intermediate generic repository redeclaring the method as the bound is now expanded to Object and not Serializable, as it did in 1.x.
We now rather check for the method name ending in …ById which is much simpler anyway.
Use ConcurrentHashMap in AnnotationBasedPersistentProperty for thread-safe annotation caching. Reintroduce eager cache check to prevent lambda instances on positive cache hits.
We now make sure that type expressions cannot be used in SpEL expressions handled by MapDataBinder. They're gonna be rejected by considering the property not writable. SpEL expression evaluation errors are now forwarded as NotWritablePropertyException to make sure the failure gets handled as if the property referred to doesn't exist.
Removed unnecessary imports. Tiny refactoring to pull exception creation into static helper method. Made methods static in test cases where possible.
Original pull request: #273.
Using Instant as internal data type since it's a point in time without time zone which LocalDateTime isn't. Added necessary converters. Fixed one JodaTime converter that used UTC to use SystemDefault like other similar converters.
In case of a conversion failure the error message now contains the source type.
Original pull request: #273.
If a query method now uses e.g. a Vavr Set as return type, we now also use a potential source List as input for the LinkedHashSet, even if that changes the characteristics (duplicate policy etc.) of the result. This is consistent with our general handling of collections as we're using a Spring ConversionService for collection mapping anyway.
In general the new conversion algorithm is driven by the expected target type first:
- i.v.c.Seq -> i.v.c.List
- i.v.c.Set -> i.v.c.LinkedHashSet
- i.v.c.Map -> i.v.c.LinkedHashMap
If none of the declared types is assignable we fall back to the previous algorithm choosing an implementation as close as possible to the original source value:
- j.u.List -> i.v.c.List
- j.u.Set -> i.v.c.LinkedHashSet
- j.u.Map -> i.v.c.LinkedHashMap
Removed some obsolete full qualifications of types.
We now inspect Kotlin's Metadata annotation to determine the kind of a Kotlin class.
Previously we used Kotlins internal API to introspect classes. Because this API is not public and can be changed at any time we rely on Kotlins annotations as they are supposed to not change in near future.
Original pull request: #269.
We now prevent the superfluous creation of a MethodParameter and TypeDescriptor instance in repository method execution in case the value to be returned already is an instance of the expected method return type.
In CustomRepositoryImplementationDetector, we now immediately hand the Environment to the constructor of ClassPathScanningCandidateComponentProvider instead of setting it afterwards. This prevents a default StandardEnvironment from being created in the previously used constructor.
We now deploy a custom BeanPostProcessor to customize RequestMappingHandlerAdapter instances by prepending a ProxyingHandlerMethodArgumentResolver (requiring a @ModelAttribute) to the list of resolved HandlerMethodArgumentResolvers to make sure the settings defined in the annotation are applied but the projecting way of data binding is still used.
Introduced RepositoryFactorySupport.getProjectionFactory(…) to create a ProjectionFactory to be used for repository instances created. The default implementation uses the SpelAwareProxyProjectionFactory.
The ProjectionInformation implementation is now a named class so it can be used for more specialized implementations.
Original pull request: #243.
Related issue: DATAJPA-1173.
Previously, a call to AbstractMappingContext.getPersistentEntity(PersistentProperty) would've added potentially leniently added the type of the given PersistentProperty, no matter whether it's actually considered to be an entity in the first place. We now defensively check for whether the given property is to be considered an entity (taking potentially registered converters into account) before the potentially entity-creating by-type lookup.
AbstractMappingContext.hasPersistentEntityFor(…) now also properly consideres the empty Optional as non-presence as that is held to allow to distinguish between a type completely unkown to the context, or already known but not considered a persistent entity.
Related pull request: #258.
In AbstractPersistentProperty, we now resolve the potentially generic return and parameter types of getters and setters. To achieve that Property has now been made aware of the actual owning type.