We now use the rootObject of the delegates context as the rootObject for the expression evaluation as well as the arguments of the current method call are available via positional indices as well via the special variable called "args".
Added minimalistic Security Context infrastructure that mimics that from Spring Security to ease testing.
Referenced appropriate JIRA issues.
We now treat the result of the SpEL expression evaluation as Object instead of just String in ExpressionAwareParameterBinder. We now prefer index based parameter binding over named parameter binding iff only SpEL expression parameters are present. We now make named parameters available as variables in SpEL expressions.
We now support the dynamic discovery and binding of SpEL Expression parameters in query derivation. Introduced ExpressionAwareParameterBinder for generic SpEL expression evaluation support.
We now support the discovery and dynamic registration of SpEL expression parameters in String based queries. Introduced an ExpressionEvaluationContextProvider that provides access to
a potentially shared SpEL EvaluationContext that is defined in the application context. This allow shared spring beans to be used within query expressions.
The SpEL expressions are evaluated in org.springframework.data.jpa.repository.query.SpelExpressionStringQueryParameterBinder.potentiallyBindSyntheticParameters(T) by using a hierarchal EvaluationContext with the RootObject set to the current method arguments.
We enhanced the parsing of ParameterBindings in ParameterBindingParser to support "synthetic" Parameters like SpEL expressions that should be evaluated at query time.
This feature works with Hibernate, EclipseLink as well as OpenJPA.
We currently support those variants:
Indexed parameter:
@Query("select c from Customer c where c.firstname = ?1 and c.attribute1 like ?#{[0] + ' ' + [1]})
To determine the index for the expression parameter we determine the max parameter index present and use that as an offset to generate appropriate parameter indices.
Named parameter:
@Query("select c from Customer c where c.firstname = :firstname and c.attribute1 like :#{[0] + ' ' + [1]})
whereby we generate a name like __$synthetic$__0 for SpEL parameter expression.
The custom handling for Blobs applies to strict conversion as it uses the simple method return type to decide whether to trigger a conversion. It now rather uses the returned domain type which automatically unwraps wrapper types like Guava's Optional.
Applied some polishing to the ConversionService setup in JpaQueryExecution to make more obvious that it's only mean to execute very specific conversions.
Added Guava as test dependency and explicit dependency for the Mysema APT plugin as the test scope only would make it invisible for the plugin.
JPA requires mapping file locations to be classpath relative. Previously we handed the full path to the file (including protocol and JAR path) to the provider, which they happened to understand by accident. To be more spec compliant, we now massage the detected URIs into the expected format.
Original pull request: #81.
Previously, we only checked the version attribute's value against null, which effectively invalidly reported a new entity being non-new in case it used primitive types for the version attribute (as it has a default value then).
We now explicitly check for primitive version property types and consider default values to indicate new state.
We now throw a dedicated InvalidJpaQueryMethodException with a more concrete exception message if we encounter a query method that is annotated with @Query(value = "…", native = true) and erroneously uses a Pageable or Sort parameter. Previously we only threw a IllegalStateException which was then recovered by the CreateIfNotFoundQueryLookupStrategy which tried to do query method derivation as a last resort. This resulted in a cryptic exception message to be thrown that indicates the derivation failure rather than the original error.
Original pull request: #97.
We now support to restrict the results of a query method via the "Top" or "First" keyword within the method name. We adjust the firstResult offset of the query in case we detect a tighter bound on the result size limit form the derived query method that is smaller than the page size of the given Pageable.
Added test cases for Paged and Sliced query executions.
Original pull request: #96.
We now delegate the exists(…) check to findOne(…) in SimpleJpaRepository for entities that have a complex composite id via @IdClass. Previously we tried to generate a string based count query in that case, which didn't work since the parameter types for the IdClass attributes didn't match the values returned by entityInformation.getCompositeIdAttributeValue(…).
Polished JavaDoc in JpaEntityInformation.
Original pull request: #95.
Stated more explicitly that we perform a lookup for an EntityManagerFactory bean with the name "entityManagerFactory" by default for the entity-manager-factory-ref attribute.
Original pull request: #94.
Special characters like french accents (e.g., abonnés) were not allowed anymore (was in SD JPA 1.2) in named parameter bindings. Adjusted regex in StringQuery to cover a broader list of characters.
Original pull request: #93.
We now support to specify just the projection part for the count query generation via the "countProjection" property of the @Query annotation.
This avoids having to repetitively specify parts of the original query.
Original pull request: #84.
Some JpaProviders (read: Hibernate in combination with Hibernate Envers) sometimes return null values from ManagedType.getJavaType() for embedded types values.
We now explicitly check for null values before adding the type to the initial entity set processed by the mapping context.
Related pull request: #89.
The main problem was a bug in querydsl 3.3.2 that has been resolved resolved in querydsl 3.3.3 to which we just updated in in spring-data-build/#70.
Cleaner usage of querydsl API and less brittle casting. Added test case for sorting by nested association property that is wrapped in a function, e.g. lower(…).
Original pull request: #87.
Added support for JPA 2.1 stored procedures mapping for repository methods. Introduced @Procedure annotation for declaring stored procedure metadata. Repository methods backed by stored procedures are represented as a StoredProcedureJpaQuery that is constructed by JpaQueryFactory#fromProcedureAnnotation.
Enhanced JpaQueryLookupStrategy to support @Procedure. Introduced StoredProcedureAttribute to capture the derived configuration for a stored procedure query.
The stored procedure needed for the tests is created via the schema-stored-procedures.sql script that is picked up by the customized DataSource definition in infrastructure.xml.
Added new test class UserRepositoryStoredProcedureTests to be able to exclude those tests for OpenJPA. OpenJPA tests don't work with hsqldb 2.x and use hsqldb 1.x instead which doesn't support stored procedures.
Original pull request: #80.
Spring Data Commons introduced a generic mechanism to post process the results of a repository method execution to potentially mitigate type differences between the result of the execution and the declared method return type. Thus we can remove the custom ConversionService usage implemented in JpaQueryExecution.
Related tickets: DATACMNS-483.
StringQuery now hints to the usage of @Param on query method parameters if named parameters are used and parameter names were not declared.
Original pull request: #77.
JpaMetamodelEntityInformation prefers the entity name from the JPA meta-model over the one derived from the simple class name. Documented limitation of an entity name customized through XML mapping metadata will not be considered in the SpEL support for manually defined query methods.
Original pull request: #76.
Updated Spring Data Commons and Spring Data Build version in pom.xml. Update pom.xml to use milestone repository. Update reference documentation to use recent Spring Data Commons version. Update changelog to reflect recent changes / releases. Update version in notice & readme.
Original pull request: #75.
We now execute a query as a SingleEntityExecution if the return-type of the particular query-method is an basic char[],Character[], byte[], Byte[].
Previously we tried to do an CollectionExecution which didn't return all elements of the actual result (e.g. the byte[]).
Although EclipseLink and Hibernate support the use of array elements in projections OpenJPA seems not to. Filed https://issues.apache.org/jira/browse/OPENJPA-2484 to track the issue. Since OpenJPA prevents the bootstrap of the whole test suite I had to comment the query method + tests out. Tested Hibernate / EclipseLink by temporarily excluding all OpenJPA tests from the test-suite.
Original pull request: #71.
Removed the additional deleted flag in @Query as we currently already ship with a method to manually implement delete-queries (using @Modifying and a manually defined JPQL query).
Tiny optimization in DeleteExecution.
Original pull request: #66.
Added implementation of deleteBy / removeBy support for JPA backed repositories. We delete entities by looking them up with the appropriate query and delete them afterwards via entityManager.remove(...). This is rather inefficient but provides the benefit of being able to use the query derivation mechanism for entity deletion as well.
Original pull request: #66.
We now support load-graph / fetch-graph QueryHints on repository query methods, which are applied when a JPA 2.1 capable JPA implementation is used. We explicitly reject the usage of those hints in case the user is running a JPA 2.0 provider.
FetchGraphs / LoadGraphs can now be defined on the Entity via the @NamedEntityGraphs annotation.
@Entity
@QueryEntity
@NamedEntityGraphs(@NamedEntityGraph(name = "GroupInfo.members", attributeNodes = @NamedAttributeNode("members")))
public class GroupInfo {
@ManyToMany List<GroupMember> members = new ArrayList<GroupMember>(); //default fetch mode is "lazy".
}
The entity graph "GroupInfo.members" overwrites the fetch-mode of the members collection to be "eager".
The entity graph to be used can now configured on a repository query method.
@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {
@EntityGraph("GroupInfo.members")
GroupInfo getByGroupName(String name);
}
The new method JpaQueryMethod#getEntityGraph analyses an @EntityGraph annotation and constructs a new JpaEntityGraph value object that contains the information form the annotation. The new method AbstractJpaQuery#applyEntityGraphConfiguration tries to apply the given EntityGraph configuration if the used JPA persistence provider supports the JPA 2.1 spec.
Changed the class path order such that EclipseLink is now placed before the eclipse dependency. EclipseLink references the JPA 2.1 API and allows us to provide type-safe support for the new JPA 2.1 features.
Original pull request: #74.
Removed custom querydsl left join generation for order fields.
The recent versions of Querydsl already do this properly - so there is no need for us anymore to add left-joins ourselves.
Previously we had to generate additional left-joins since Querydsl did not support ordering by an attribute that was not part of the projection.
Original pull request: #73.