Do not include the result value in the exception message to avoid data exposure.
Improve data flow to avoid superfluous null checks.
See #2290.
Original Pull Request: #2291.
We now throw UnsupportedOperationException when a projected value cannot be returned because it cannot be brought into the target type, either via conversion or projection.
This exception improves the error message by avoiding throwing IllegalArgumentException: Projection type must be an interface from the last branch that falls back into projections.
Closes#2290.
Original Pull Request: #2291
We now support nullable wrappers for projection interfaces. Getters are inspected whether their return type is a supported nullable wrapper. If so, then the value can be wrapped into that type. Null values default in that case to their corresponding empty wrapper representation.
Original Pull Request: #459
Replace the few occurrences where SLF4J was being used directly so that
all logging now happens via commons-logging. The log patterns used in
SLF4J messages have been replaced with `LogMessage` which was introduced
in Spring Framework 5.2.
Original pull request: #448.
We now use ConcurrentHashMap as type instead of HashMap to properly synchronize concurrent updates to missing cache elements.
The previously used HashMap was not thread-safe so concurrent modifications resulted in ConcurrentModificationException.
We now attempt to use private MethodHandles lookup as the first mechanism to resolve a MethodHandle for default interface methods and fall back to reflection-based Lookup construction if private lookup is not available. Reflective availability is checked lazily to prevent illegal access on enum constant construction. This approach prevents an illegal access which was logged by attempting a reflection-based lookup first.
We also introduced a FALLBACK mechanism to split encapsulated access from a fallback mechanism.
Original pull request: #307.
ProxyProjectionFactory and ResultProcessor require a DefaultConversionService to convert values for projection proxies and to post-process query method results. Creating instances of these types requires an instance of the conversion service which previously created a DefaultConversionService instance (along all converter registrations) upon ProxyProjection/ResultProcessor instantiation.
We now use the shared instance that is initialized once and shared across all ProxyProjection/ResultProcessor instances to reduce garbage and improve the CPU profile.
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.
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.
We now attempt MethodHandle lookup with deep reflection capabilities via MethodHandles.privateLookupIn(…) to properly resolve default interface methods on interfaces with package-protected visibility. This API is only available in Java 9 so we need to rely on reflection.
Original pull request: #251.
We now forward method parameters of methods on projection interfaces to the expression evaluation. The parameters are exposed via an array named "args".
Marked all packages with Spring Frameworks @NonNullApi. Added Spring's @Nullable to methods, parameters and fields that take or produce null values. Adapted using code to make sure the IDE can evaluate the null flow properly. Fixed Javadoc in places where an invalid null handling policy was advertised. Strengthened null requirements for types that expose null-instances.
Removed null handling from converters for JodaTime and ThreeTenBP. Introduced factory methods Page.empty() and Page.empty(Pageable). Introduced default methods getRequiredGetter(), …Setter() and …Field() on PersistentProperty to allow non-nullable lookups of members. The same for TypeInformation.getrequiredActualType(), …SuperTypeInformation().
Tweaked PersistentPropertyCreator.addPropertiesForRemainingDescriptors() to filter unsuitable PropertyDescriptors before actually trying to create a Property instance from them as the new stronger nullability requirements would cause exceptions downstream.
Lazy.get() now expects a non-null return value. Clients being able to cope with null need to call ….orElse(…).
Original pull request: #232.
If you previously asked ProxyProjectionFactory for a proxy of an interface which the target instance already implements, it created a proxy although it could've returned the instance as is. It's now actually doing that avoiding superfluous proxy creation.
To avoid the repeated scanning of projection interfaces for property descriptors we now cache the ProjectionInformation instances created via ProjectionFactory.getProjectionInformation(…). Adapted SpelAwareProxyProjectionFactory to now apply its customizations in newly introduced createProjectionInformation(…).
Removed the deprecated implementation of ResourceLoaderAware in favor of BeanClassLoaderAware. Removed deprecated ProjectionFactory.getInputProperties() in favor of ….getProjectionInformation(). Removed the Java conditional to add a MethodInterceptor for default methods. Adapted test cases.
DefaultMethodInvokingMethodInterceptor now contains two alternative implementations, one compatible to Java 8, one for Java 9.
Original pull request: #223.
Removed the additional methods that reflectively checked for the Stream type and whether a Method instance is a default method. Turned utility classes into interfaces where possible. Make use of Lombok's @UtilityClass where not.
Removed obsolete implementation class in StreamUtils in favor of a lambda.
Make use of lambdas and method references though out the codebase. Remove no longer required generic type parameters.
Additionally remove unused imports and replace single element list initialization with dedicated singletonList.
Use Assertion overloads taking Supplier for dynamic assertion error messages.
Re added PropertyDescriptor collection. Looks like the method got dropped during one of the rebase operations.
Additionally make use of .distinct() name collection in tests as descriptors might appear multiple times for the same property name.
We now exclude getter methods that are default methods from the consideration which properties of a projection interface are considered input properties in the first place.
Some additional Java 8 polish in DefaultProjectionInformation.
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.
Projection types annotated with @ProjectedPayload can now be used as parameters for @RequestBody annotated Spring MVC controller method parameters.
Accessor methods will be translated into JSON path property expressions which can be customized by using the @JsonPath annotation. The methods are allowed to return simple types, nested projection interfaces or complex classes which will will be mapped using a Jackson ObjectMapper.