We now decline sort expressions that contain functions such as ORDER BY LENGTH(name) when used with repository having a String query defined via the @Query annotation.
Think of a query method as follows:
@Query("select p from Person p where LOWER(p.lastname) = LOWER(:lastname)")
List<Person> findByLastname(@Param("lastname") String lastname, Sort sort);
Calls to findByLastname("lannister", new Sort("LENGTH(firstname)")) from now on throw an Exception indicating function calls are not allowed within the _ORDER BY_ clause. However you still can use JpaSort.unsafe("LENGTH(firstname)") to restore the behavior.
Kudos to Niklas Särökaari, Joona Immonen, Arto Santala, Antti Virtanen, Michael Holopainen and Antti Ahola who brought this to our attention.
JpaPersistentEntityImpl.isEntity() currently called a method on the JPA meta-model, catching an exception to indicate the given type is not managed. We're now rather iterate over all managed types to avoid the overhead of the exception being thrown and handled immediately.
Previously the first property was checked for being a collection to trigger collection contains handling. This is wrong for nested property traversals as they might end up in a String for which a like binding has to be applied then.
We're now inspecting the leaf property for being a collection to trigger that special binding.
Added instructions to the reference documentation on how to register the AuditingEntityListener using JPA's @EntityListeners annotation.
Original pull request: #163.
CrudMethodMetadata exposed by the CrudMethodMetadataPostProcessor previously used an AbstractLazyCreationTargetSource to lookup the thread-bound instance. That instance however is cached and never released so that all subsequent calls to it returned the same (and in most cases wrong) instance.
We're now implementing TargetSource directly to make sure we obtain a fresh instance on every access of the CrudMethodMetadata proxy.
Replacing bean name "foo" with more meaningful value injected via constant as a bean probably shouldn't have "foo" as its name when everything else has meaningful values defined in constants. Renamed bean and extracted constant alongside others referenced within the file.
Original pull request: #159.
The if a collection expression is concluded with a Contains keyword, we now translate that into a "member of"-expression on the criteria query. This allows to check whether a collection property contains a singular value.
List<User> findByRolesContaining(Role role);
This will return all users that have the given role.
Tweaked the lookup of a version property on a mapped superclass. Hibernate doesn't expose itself as being very supportive in that: on versions below 4.3 the method primarily intended to look it up (IdentifiableType.getVersion(…)) expects you to hand in exactly the type of the property you're trying to find in the first place. Awesome, not.
If this fails, we now explicitly traverse the singular attributes and recursively traverse super types. Unfortunately, on the Hibernate version broken as defined above, the check for attribute.isVersion() fails even for the version property as the implementation holds all singular attributes with one for the version property which is not marked as such.
tl;dr; - everyone trying to use @Version on a mapped superclass and a primitive identifier in an entity on Hibernate 4.3 will still have to implement Persistable to make sure EntityManager.persist(…) is used for new entities.
The thread-local proxy for the CrudMethodMetadata is now created using the bean ClassLoader, which the repository factory gets set from the container.
Renamed the property for the post processor and its lookup method.
The application of sort expressions is guarded by the detection of join aliases to potentially prefix the sort expression with the default alias. In case a raw property reference to sort by started with a join alias the property name wasn't prefixed. We now explicitly check for a start with the alias followed by a dot.
We tweaked the regular expression to detect query aliases to correctly use the whitespace character class \s instead of a simple space to make sure we don't get fooled by other whitespace characters like tabs and line breaks.
Added test case to AbstractAuditingViaJavaConfigRepositoryTests that uses the SampleEvaluationContextExtension to demonstrate access of "security" context objects as well as dynamic SpEL Expression binding.
Needed to add FixedDate helper class to ease checks for modification time stamps.
Original pull request: #152.
Instead of peeking at internals of the JPA Query instance we no simply use Query.unwrap(…) as this achieves the same thing and avoids issues with proxied Query instances.
Reworked integration test to make it work on EclipseLink, too. Simply checking for new no joins doesn't work here as it even adds joins for plain attribute traversals using root.get(…). We're now using Mockito to verify the expected behavior on the interaction level instead of the Root's state.
Removed superfluous finals. Added some Javadoc where necessary.
Original pull request: #151.
QueryUtils.toExpressionRecursively(…) now also checks the provided root for already existing fetches to avoid creating superfluous join.
Original pull request: #151.
If parameter names for derived queries use names that collide with reserved keywords in JPQL (e.g. key) switching on Java 8 parameter name discovery previously caused the query execution to fail.
We now check whether the parameter has been explicitly named (using the @Param annotation) and only use the name if so.
With 83a3db we switched from a GenericConversionService to DefaultConversionService to be able to transparently convert non-Long results for count query executions into Longs.
Unfortunately the additional converters registered in DefaultConversionService now also kick in on the early conversion attempt. This is especially problematic for collection results that are wrapped into a (Completable)Future as the CollectionToObjectConverter opts into conversions from an arbitrary collection to objects trying to figure out element type conversion later on.
We now explicitly deregister the conversions from Collection to Object (which is the convertible pair that CollectionToObjectConverter registers for) to avoid the conversion service to try to convert those values.
We now only validate parameter names if the declared query actually uses named parameters.
This is mainly needed in context of an (accidentally) mixed use of named parameters with indexed placeholders which can occur if compiling with parameters is activated on Java 8 (i.e. using -parameters) but indexed parameters are used in the query definition.
AbstractStringBasedJpaQuery now considers the native flag of the underlying JpaQueryMethod when creating count queries.
Had to widen the return type of AbstractJpaQuery.createJpaQuery(…) to Query to accommodate the return value EntityManager.createNativeQuery(…). Tweaked the implementation of PagedExecution to handle non-Long return values potentially converting them to longs to retain API.