Commit Graph

252 Commits

Author SHA1 Message Date
Oliver Gierke
5c906ce73c DATAJPA-622 - Polishing.
Renamed CustomAbstractPersistableIntergrationTests to AbstractPersistableIntergrationTests. Reordered declarations in persistence(2).xml to make sure we retain alphabetic sorting.

Original pull request: #115.
2014-11-24 17:37:23 +01:00
Thomas Darimont
8418263461 DATAJPA-622 - AbstractPersistable.isNew() is now annotated with @Transient.
We now mark AbstractPersistable.isNew() property as @Transient for JPA in order to make sure that no JPA provider complains about a missing setter in case a user derives a domain entity from AbstractPersistable. Without this it isn't possible to bootstrap a PersistenceContext.

Original pull request: #115.
2014-11-24 17:37:15 +01:00
Oliver Gierke
cd6d7b6e5b DATAJPA-630 - Add IdentifierAccessor implementation that avoids proxy resolution for id lookups.
We now customize the IdentifierAccessor returned from JpaPersistentEntity.getIdentifierAccessor(…) to allow the identifier lookup use persistence provider specific means. This is needed to make sure we lookup identifiers for proxies correctly for which a field value lookup would not succeed (as the providers do not pre-populate the identifier field).
2014-11-24 13:32:44 +01:00
Oliver Gierke
e067f01fa4 DATAJPA-623 - Fixed package cycles accidentally introduced.
Moved JpaEntityMetadata and DefaultJpaEntityMetadata to query package to avoid a cyclic dependency to it. Jpa21Utils now also resides in the query package as the util package must not depend on other project packages.

Updated the Sonargraph architecture description by adding new architectural artifacts for mapping, the CDI support and utilities. Defined allowed dependencies more strictly to detect architecture violations more aggressively.
2014-11-10 15:50:54 +01:00
Oliver Gierke
1aac6809ea DATAJPA-605 - JpaPersistentProperty implementation now detects JPA's @Version annotation.
Added override for JpaPersistentPropertyImpl.isVersionProperty() to also consider properties annotated with JPA's @Version annotation as version property.

Related pull request: #108.
2014-11-10 14:37:36 +01:00
Thomas Darimont
fb76c9d422 DATAJPA-477 - Avoid query creation in PagedExecution if count query returns 0.
We now skip the query creation if we detect that the preceding count query returned 0 or no results. Previously we always created a query in every case even if it was not necessary.

Original pull request: #113.
2014-11-10 14:24:56 +01:00
Oliver Gierke
be0fcad483 DATAJPA-619 - JpaPersistentPropertyImpl now considers JPA access definition annotations.
JpaPersistentPropertyImpl now looks up both Spring Data and JPA access type definition annotations from both property and type level. Property-level definitions trump type-level ones, Spring Data ones trump JPA ones if defined on the same level.

In support of DATAREST-269 to be able to work around id access issues when working with proxies created by JPA providers.

Related ticket: DATAREST-269.
2014-10-29 11:24:38 +01:00
Thomas Darimont
c585ed3c3b DATAJPA-617 - Avoid potential transaction rollbacks during named query lookups.
We now use a dedicated EntityManager for the named query lookup in NamedQuery.hasNamedQuery(…). Previously we used the given EntityManager to lookup the named query which will cause the transaction to be rolled back due to the Exception thrown in the case that the named query couldn't be found.

Added fast path to NamedQuery.lookupFrom(…) that now uses NamedQuery.hasNamedQuery(…) to test if a query exists or not. Pulled the check for the presence of a named count query from doCreateCountQuery(…) up to the NamedCountQuery constructor. This makes sure that the check is only performed once.

Original pull request: #110.
2014-10-29 09:56:42 +01:00
Thomas Darimont
bacf6cce26 DATAJPA-612 - Allow @EntityGraph on a method inherited from JpaRepository.
We now respect the @EntityGraph annotations on redeclared CRUD methods. CrudMethodMetadata now looks for @EntityGraph annotations, and - if present - the appropriate entity graph configuration is applied within SimpleJpaRepository.applyRepositoryMethodMetadata(…).

Previously we mistakenly treated the @EntityGraph annotation as a Query annotation which triggered a query resolution process that tried to find a named or create a derived query and failed. Removed @QueryAnnotation from @EntityGraph, since it should only be used to mark store specific @Query annotations.

Renamed Jpa21QueryCustomizer to Jpa21Utils. Moved Jpa21Utils to org.springframework.data.jpa.util to avoid potential dependency cycles.

Added EclipseLink and OpenJPA specific subclasses for the EntityGraphRepositoryMethodsIntegrationTests to make sure the tests are executed for EclipseLink and OpenJPA as well.

Original pull request: #109.
2014-10-22 15:07:27 +02:00
Oliver Gierke
6ea82fa1c5 DATAJPA-608 - JpaPersistentPropertyImpl.isEntity() now uses getActualType(). 2014-09-15 14:11:12 +02:00
Thomas Darimont
ebb2be942a DATAJPA-596 - Allow sorting by Querydsl operator expression.
Added test case for sorting by Querydsl operator expression.

Original pull request: #107.
2014-08-26 14:00:03 +02:00
Mark Paluch
cd34005349 DATAJPA-584 - Add support for custom implementations in CDI.
Adapted to API changes in Spring Data Commons. Added test cases to make sure the lookup of custom repository implementations works.

Original pull request: #105.
2014-08-07 14:04:19 +02:00
Oliver Gierke
dfcaeb6a52 DATAJPA-581, DATAJPA-582 - Fixed isNew(…) detection in JpaMetamodelEntityInformation.
We now generally consider all non-null values of a non-primitive @Version attribute indicating a non-new entity.
2014-08-06 09:01:04 +02:00
Oliver Gierke
60c866442a DATAJPA-362 - Added another test case to make sure invalid like bindings are rejected.
Related ticket: DATAJPA-292.
2014-07-18 11:35:42 +02:00
Oliver Gierke
1998874c47 DATAJPA-576 - Improvements in JpaMappingContext setup in configuration.
Refactored JpaMappingContext to be able to work with multiple instances of Metamodel. This removes the need to wire a dedicated one in JpaMetamodelContextFactoryBean and thus makes it independent of a particular EntityManager(Factory). This significantly eases the implementation of the configuration integration.
2014-07-16 16:26:39 +02:00
Oliver Gierke
3467d9257d DATAJPA-574 - Implementation of QueryDslPredicateExecutor now considers lock mode and query hints.
The Querydsl query creation now also leverages the CrudMethodMetadata instance held in SimpleJpaRepository to apply lock mode settings and query hints to the query to be executed.
2014-07-16 13:51:46 +02:00
Oliver Gierke
2b4dfa2aeb DATAJPA-575 - Adapted to deprecation removals in Spring Data Commons.
Related ticket: DATACMNS-469.
2014-07-16 12:04:34 +02:00
Christoph Strobl
68ed8a9082 DATAJPA-568 - Fix is-new detection for primitive version properties.
Some persistence providers do not bump the version number in an initial call to EntityManager.persist(…). Thus, in case of a primitive version property we cannot distinguish between a new entity and one already persisted. We now fall back to id inspection whenever we find a primitive version property.

Original pull request: #103.
2014-07-10 14:28:00 +02:00
Oliver Gierke
59176d6a0a DATAJPA-564 - Polishing of SpEL integration test cases. 2014-07-10 12:18:26 +02:00
Thomas Darimont
26cda66de8 DATAJPA-564 - Allow SpEL expressions to be the only consumer of query method parameters.
Since eclipselink doesn't reliably report whether a given query contains parameter we try to set query-parameters via brute force in SESQPB.
2014-07-10 11:46:52 +02:00
Thomas Darimont
0602084c0e DATAJPA-564 - Allow SpEL expressions to be the only consumer of query method parameters.
We now allow the parameters of query methods to also be exclusively consumed by expressions within a given query string. Previously this wasn't possible due to to strict checks for parameter usage in JpaQueryMethod.
Relax check for query param usage in JpaQueryMethod.
Enabled HSQLDB support for oracle syntax to be able to use the ROWNUM() function for pagination.
2014-07-10 11:46:52 +02:00
Thomas Darimont
55f1131b2f DATAJPA-564 - Allow SpEL expressions to be the only consumer of query method parameters.
We now allow the parameters of query methods to also be exclusively consumed by expressions within a given query string. Previously this wasn't possible due to to strict checks for parameter usage in JpaQueryMethod.
Relax check for query param usage in JpaQueryMethod.
2014-07-10 11:46:52 +02:00
Oliver Gierke
841bb22906 DATAJPA-564 - Extracted SPI into Spring Data Commons. 2014-07-10 11:46:51 +02:00
Thomas Darimont
1a89612f25 DATAJPA-564 - Added EvaluationContextExtension SPI for configuring extensions to the EvaluationContext. 2014-07-10 11:46:51 +02:00
Thomas Darimont
bcdb2881a5 DATAJPA-564 - Renamed ExpressionEvaluationContextProvider to EvaluationContextProvided. 2014-07-10 11:46:51 +02:00
Thomas Darimont
09b6a49146 DATAJPA-564 - Removed support for SpEL expressions in derived queries.
We came to the conclusion that allowing SpEL expressions as parameters in derived queries would create incentives for users to mess with the low-level Expressions API in high level user code. Therefore we decided to remove this feature - for now.
2014-07-10 11:46:51 +02:00
Thomas Darimont
1879fea1f0 DATAJPA-564 - Expose invocation arguments as well as delegate root object properties via root expressions.
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.
2014-07-10 11:46:42 +02:00
Thomas Darimont
b09588f922 DATAJPA-564 - More robust handling of SpEL expressions in String queries.
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.
2014-07-10 11:34:24 +02:00
Thomas Darimont
a94a807bb3 DATAJPA-564 - Add support for dynamically evaluating SpEL expressions in derived queries.
We now support the dynamic discovery and binding of SpEL Expression parameters in query derivation. Introduced ExpressionAwareParameterBinder for generic SpEL expression evaluation support.
2014-07-10 11:34:24 +02:00
Thomas Darimont
c4f245b11e DATAJPA-564 - Support for SpEL based parameter expressions in String based queries.
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.
2014-07-10 11:34:24 +02:00
Oliver Gierke
2db3b9b5df DATAJPA-506 - Re-enabled query method invocation with wrapper type results.
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.
2014-07-07 17:37:27 +02:00
Thomas Darimont
fe55862bcf DATAJPA-519 - Spec compliant mapping file URI handling in ClasspathScanningPersistenceUnitPostProcessor.
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.
2014-06-27 19:07:56 +02:00
Thomas Darimont
68e2ee5ed9 DATAJPA-506 - Add support for conversion of Blob values to byte[] in native queries.
JpaQueryExecution no applies type conversion for Blob instances to be able to return byte[] from repository calls.

Original pull request: #72.
2014-06-26 17:04:32 +02:00
Oliver Gierke
af45da40c6 DATAJPA-561 - JpaMetamodelEntityInformation now treats primitive version properties correctly.
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.
2014-06-26 16:15:03 +02:00
Thomas Darimont
2a11a679a2 DATAJPA-554 - Avoid falling back to query derivation for invalid native queries.
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.
2014-06-17 18:03:09 +02:00
Thomas Darimont
43d035fe54 DATAJPA-551 - Add support for limiting the query result in the query derivation mechanism.
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.
2014-06-17 13:38:52 +02:00
Thomas Darimont
09d32cb3f5 DATAJPA-527 - Improved handling of CrudRepository.exists(ID) entities with complex composite id.
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.
2014-06-17 13:32:15 +02:00
Thomas Darimont
0480843322 DATAJPA-545 - Fixed regression in discovery of StringQuery parameters.
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.
2014-05-22 11:56:47 +02:00
Oliver Gierke
13346c0115 DATACMNS-494 - Fix test setup in JpaRepositoriesRegistrarUnitTests.
We now explicitly set an Environment in JpaRepositoriesRegistrarUnitTests to make sure the registrar can work correctly.
2014-05-20 16:48:10 +02:00
Thomas Darimont
122d9c5ea2 DATAJPA-456 - Add support for specifying only the projection part of a custom count query.
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.
2014-05-19 19:37:12 +02:00
Thomas Darimont
076b017d18 DATAJPA-525 - Guard against null types returned from JPA meta-model.
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.
2014-05-19 12:55:20 +02:00
Thomas Darimont
4d63856dde DATAJPA-510 - Fix regression when sorting by property of associated object.
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.
2014-05-19 12:11:31 +02:00
Thomas Darimont
2c2355bc93 DATAJPA-499 - Querydsl now uses the null-handling configured on the Sort.Order.
We now propagate the null-handling hint defined in Order to an appropriate Querydsl null handling hint.

Original pull request: #82.
2014-04-29 09:07:55 +02:00
Thomas Darimont
09535813c2 DATAJPA-455 - Add support for stored procedure backed repository methods.
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.
2014-04-28 12:43:46 +02:00
Oliver Wehrens
7c6f4528ef DATAJPA-513 - Improve error message on missing @Param on query method parameter.
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.
2014-04-14 10:39:13 +02:00
Thomas Darimont
ff0170967d DATAJPA-509 - JpaMetamodelEntityInformation now considers entity name from JPA meta-model.
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.
2014-04-14 09:43:02 +02:00
Thomas Darimont
44d7e2ef24 DATAJPA-505 - Projections for basic primitive arrays should use SingleEntityExecution.
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.
2014-03-31 15:03:07 +02:00
Oliver Gierke
3ff4f94c68 DATAJPA-460 - Reduce implementation to core requested feature.
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.
2014-03-31 14:38:14 +02:00
Thomas Darimont
99ae3c4567 DATAJPA-460 - Support query creation for deleteBy / removeBy prefix.
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.
2014-03-31 14:38:08 +02:00
Thomas Darimont
dd64fe21ea DATAJPA-466 - Add support for lazy loading configuration via JPA 2.1 fetch-/loadgraph.
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.
2014-03-30 16:42:36 +02:00