Changed the implementation of both the JSON Path and XPath based projecting HttpMessageConverters to make sure the cached decisions don't depend on the media type. Reuse the evaluation of the media type in AbstractHttpMessageConverter.
Previously TransactionalRepositoryFactoryBeanSupport.setBeanFactory(…) didn't invoke the method of the super class preventing the BeanFactory to be propagated to the repository factory resulting in the ProjectionFactory implementation created being unaware of the BeanFactory and thus no bean references being available in projection interfaces.
When a recursive decent operator is used in a JSON Path expression there's no way to get out of the array mode again to indicate one is interested in a particular element (e.g. "the first one no matter where in the document") [0]. We now work around this by always letting the parser return lists, so that the mapping library finally kicking in can be equipped with the correct target type to create.
Unfortunately this causes arrays to be double-wrapped for definite paths so that we basically have to adapt the type handed to Jackson in another round to the unwrap the mapping result in turn [1].
[0] https://github.com/jayway/JsonPath/issues/248
[1] https://github.com/jayway/JsonPath/issues/249
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.
PageableExecutionSupport assumes that data queries are cheaper than count queries so we can apply some optimizations. We determine the total from the pageable and the results in which we don't hit the page size bounds (i.e. results are less than a full page without offset or results are greater 0 and less than a full page with offset). In all other cases we issue an additional count query.
Improved the dot-path translation of existing Querydsl Path instances by not relying on the toString() representation of the metadata but manually traversing the elements up to the root. Extracted the translation method into QueryDslUtils.
Furthermore, we now automatically insert an CollectionPathBase.any() step for Path instances of that type when reifying the paths from request attributes.
Introduced dedicated factory methods for ExampleMatcher so that it exposes whether the predicates built from Example instances have to be fulfilled all or if it's sufficient that any of them matches.
Turned the previously anonymous inner class that applies result processing to a JDK 8 Stream into a dedicated inner class to avoid JDK types being loaded on older JDKs. The previous way was causing issues due to the JVM trying to resolve the Function interface when loading the ResultProcessor class.
Original pull request: #163.
We now explicitly report the given object's type and the one expected in case of a mismatch when BasicPersistentEntity.getPropertyAccessor(…) is invoked.
We now also cache a failed property lookup so that we can return null on a subsequent call for the same invalid property name right away and don't have to reattempt the lookup unnecessarily.
The lookup for already available PersistentEntity instances now acquires a read lock to shield the execution from partially equipped PersistentEntity instances currently in creation from another thread.
Original pull request: #157.
ToEntityConverter.matches(…) now doesn't throw an exception anymore as it might be picked up by classpath scanning an the exception previously thrown causing the entire conversion attempt to abort.
We're now rather inspecting the ToEntityConverter in case the target type is a repository managed one and the ToIdConverter otherwise.
ResourceProcessor supports Streams now and adds a map(…) step to apply projections.
Also, the ProjectingConverter falls back to use a default ConversionService instance to make use of the object mapping functionality implemented in ObjectToObjectConverter, i.e. the ability to just map an object returned from the store to a DTO in case that latter exposes a constructor or factory methods taking the source instance as parameter.
Related tickets: DATAJPA-903.
Simplified conditional expressions in DefaultRepositoryInformation. Reordered test method to reflect natural order of adding.
Original pull request: #162.
Add additional check for detecting customized method where method contains generics. Overriding methods without generics already works, this patch simply makes the behavior consistent.
Original pull request: #162.
We're now correctly stating that we're preferring the delete method that takes the entity as argument over the one taking the id to match what's actually implemented.
The translation of the list of actual type parameters into an array now uses the loop index correctly. Previously, it always used the first type parameter.
Added proper equals(…) and hashCode() methods to SyntheticParameterizedType to make sure instances created for the same type information and type parameters are considered equal.
Simplified test case. Formatting in ClassGeneratingPropertyAccessorFactory.
Related tickets: DATACMNS-809.
Original pull request: #161.
Related pull request: #160.
Property accessors (getter and setter) defined on an interface require a different instruction opcode for invoking methods. We now distinguish whether a property accessor is defined on an interface and use either INVOKEINTERFACE or INVOKEVIRTUAL otherwise.
Related tickets: DATACMNS-809.
Original pull request: #161.
Related pull request: #160.
Reproduce issue accessing persistent properties from interface-based entities using the ClassGeneratingPropertyAccessorFactory.
Related tickets: DATACMNS-809.
Original pull request: #161.
Related pull request: #160.
Removed DefaultPersistentPropertyAccessorFactory as it only delegates to the class generating one. Tweaked AbstractMappingContext to actually use the latter in the first place. Introduced BeanWrapperPropertyAccessorFactory to implement the default behavior of using a BeanWrapper and initialize BasicPersistentEntity to avoid a null clause in getPersistentPropertyAccessor(…).
Removed getPersistentPropertyAccessorFactory and rather rely on ReflectionTestUtils in tests to avoid additional API being exposed.
Original pull request: #159.
PersistentPropertyAccessorFactory can be set on a BasicPersistentEntity. This is done by AbstractMappingContext once the entity is verified. This change reduces the count of PersistentPropertyAccessorFactory instances and performs the isSupported check only once, when initializing the entity.
Original pull request: #159.
Made as many methods in ClassGeneratingPropertyAccessorFactory static as possible. Some code formatting. Some warning suppressions where needed.
Original pull request: #159.
We now support generated PersistentPropertyAccessors when using Java 7 and if property/association name hashCodes are unique within a PersistentEntity.
Generated PersistentPropertyAccessors provide optimized access to properties. They use either MethodHandles or direct property/field access, depending on the visibility/final modifiers of the entity type and its members. A generated PersistentPropertyAccessor is injected into the originating class loader of the entity class to enable optimizations for package-default/protected member access.
Original pull request: #159.
We now completely ignore all core Java types (i.e. types with a package name starting with "java.") from being DTOs. This allows query methods to project on date time types, too.
The type was a workaround until an improvement in Spring Framework [0] was fixed. As we now rely on newer versions of the framework, we can remove that type.
[0] https://jira.spring.io/browse/SPR-12042
The indicator of whether custom construction is needed for a class based return type now includes whether input properties are available in the first place.
In case a DTO type exposes multiple no-argument constructors we now leniently abort the parameter name detection and let downstream users decide what to do in this particular case.
The problematic case can't be outright rejected here already as there's valid scenarios for that, e.g. in JPA the type could be used for multiple query methods, using explict constructor expressions listing arguments explicitly and thereby select one of the multiple constructors.