From e067f01fa4a3cb86282b71ed4673baa9a0321dfc Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 10 Nov 2014 15:50:54 +0100 Subject: [PATCH] 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. --- Spring Data JPA.sonargraph | 347 ++++++++++-------- .../repository/query/AbstractJpaQuery.java | 1 - .../DefaultJpaEntityMetadata.java | 4 +- .../query/ExpressionBasedStringQuery.java | 1 - .../query}/Jpa21Utils.java | 3 +- .../{support => query}/JpaEntityMetadata.java | 4 +- .../jpa/repository/query/JpaQueryCreator.java | 122 +++--- .../jpa/repository/query/JpaQueryMethod.java | 2 - .../query/StoredProcedureAttributeSource.java | 1 - .../support/JpaEntityInformation.java | 1 + .../support/JpaEntityInformationSupport.java | 2 + .../support/QueryDslJpaRepository.java | 2 +- .../support/SimpleJpaRepository.java | 2 +- .../ExpressionBasedStringQueryUnitTests.java | 1 - .../query/SimpleJpaQueryUnitTests.java | 2 - ...oredProcedureAttributeSourceUnitTests.java | 1 - .../DefaultJpaEntityMetadataUnitTest.java | 1 + 17 files changed, 260 insertions(+), 237 deletions(-) rename src/main/java/org/springframework/data/jpa/repository/{support => query}/DefaultJpaEntityMetadata.java (93%) rename src/main/java/org/springframework/data/jpa/{util => repository/query}/Jpa21Utils.java (96%) rename src/main/java/org/springframework/data/jpa/repository/{support => query}/JpaEntityMetadata.java (88%) diff --git a/Spring Data JPA.sonargraph b/Spring Data JPA.sonargraph index 9a9fd815a..d41bcefa3 100644 --- a/Spring Data JPA.sonargraph +++ b/Spring Data JPA.sonargraph @@ -1,216 +1,237 @@ - - - - + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - + - - - - + - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + + - - - + + + - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java index b251c6d2f..131d22a3d 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java @@ -28,7 +28,6 @@ import org.springframework.data.jpa.repository.query.JpaQueryExecution.PagedExec import org.springframework.data.jpa.repository.query.JpaQueryExecution.ProcedureExecution; import org.springframework.data.jpa.repository.query.JpaQueryExecution.SingleEntityExecution; import org.springframework.data.jpa.repository.query.JpaQueryExecution.SlicedExecution; -import org.springframework.data.jpa.util.Jpa21Utils; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.util.Assert; diff --git a/src/main/java/org/springframework/data/jpa/repository/support/DefaultJpaEntityMetadata.java b/src/main/java/org/springframework/data/jpa/repository/query/DefaultJpaEntityMetadata.java similarity index 93% rename from src/main/java/org/springframework/data/jpa/repository/support/DefaultJpaEntityMetadata.java rename to src/main/java/org/springframework/data/jpa/repository/query/DefaultJpaEntityMetadata.java index 8e457cd7c..80ee3a9dd 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/DefaultJpaEntityMetadata.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/DefaultJpaEntityMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jpa.repository.support; +package org.springframework.data.jpa.repository.query; import javax.persistence.Entity; diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java index 230fa87db..ac8b54e66 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQuery.java @@ -15,7 +15,6 @@ */ package org.springframework.data.jpa.repository.query; -import org.springframework.data.jpa.repository.support.JpaEntityMetadata; import org.springframework.data.repository.core.EntityMetadata; import org.springframework.expression.Expression; import org.springframework.expression.ParserContext; diff --git a/src/main/java/org/springframework/data/jpa/util/Jpa21Utils.java b/src/main/java/org/springframework/data/jpa/repository/query/Jpa21Utils.java similarity index 96% rename from src/main/java/org/springframework/data/jpa/util/Jpa21Utils.java rename to src/main/java/org/springframework/data/jpa/repository/query/Jpa21Utils.java index a23df2c8b..787c36599 100644 --- a/src/main/java/org/springframework/data/jpa/util/Jpa21Utils.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/Jpa21Utils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jpa.util; +package org.springframework.data.jpa.repository.query; import java.lang.reflect.Method; @@ -21,7 +21,6 @@ import javax.persistence.EntityGraph; import javax.persistence.EntityManager; import javax.persistence.Query; -import org.springframework.data.jpa.repository.query.JpaEntityGraph; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityMetadata.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaEntityMetadata.java similarity index 88% rename from src/main/java/org/springframework/data/jpa/repository/support/JpaEntityMetadata.java rename to src/main/java/org/springframework/data/jpa/repository/query/JpaEntityMetadata.java index c54f27c85..6c82bdc88 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityMetadata.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaEntityMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jpa.repository.support; +package org.springframework.data.jpa.repository.query; import org.springframework.data.repository.core.EntityMetadata; diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java index c6f21d25c..f239459f9 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java @@ -199,55 +199,55 @@ public class JpaQueryCreator extends AbstractQueryCreator, Expression path = toExpressionRecursively(root, property); switch (part.getType()) { - case BETWEEN: - ParameterMetadata first = provider.next(part); - ParameterMetadata second = provider.next(part); - return builder.between(getComparablePath(root, part), first.getExpression(), second.getExpression()); - case AFTER: - case GREATER_THAN: - return builder - .greaterThan(getComparablePath(root, part), provider.next(part, Comparable.class).getExpression()); - case GREATER_THAN_EQUAL: - return builder.greaterThanOrEqualTo(getComparablePath(root, part), provider.next(part, Comparable.class) - .getExpression()); - case BEFORE: - case LESS_THAN: - return builder.lessThan(getComparablePath(root, part), provider.next(part, Comparable.class).getExpression()); - case LESS_THAN_EQUAL: - return builder.lessThanOrEqualTo(getComparablePath(root, part), provider.next(part, Comparable.class) - .getExpression()); - case IS_NULL: - return path.isNull(); - case IS_NOT_NULL: - return path.isNotNull(); - case NOT_IN: - return path.in(provider.next(part, Collection.class).getExpression()).not(); - case IN: - return path.in(provider.next(part, Collection.class).getExpression()); - case STARTING_WITH: - case ENDING_WITH: - case CONTAINING: - case LIKE: - case NOT_LIKE: - Expression stringPath = getTypedPath(root, part); - Expression propertyExpression = upperIfIgnoreCase(stringPath); - Expression parameterExpression = upperIfIgnoreCase(provider.next(part, String.class).getExpression()); - Predicate like = builder.like(propertyExpression, parameterExpression); - return part.getType() == Type.NOT_LIKE ? like.not() : like; - case TRUE: - Expression truePath = getTypedPath(root, part); - return builder.isTrue(truePath); - case FALSE: - Expression falsePath = getTypedPath(root, part); - return builder.isFalse(falsePath); - case SIMPLE_PROPERTY: - ParameterMetadata expression = provider.next(part); - return expression.isIsNullParameter() ? path.isNull() : builder.equal(upperIfIgnoreCase(path), - upperIfIgnoreCase(expression.getExpression())); - case NEGATING_SIMPLE_PROPERTY: - return builder.notEqual(upperIfIgnoreCase(path), upperIfIgnoreCase(provider.next(part).getExpression())); - default: - throw new IllegalArgumentException("Unsupported keyword " + part.getType()); + case BETWEEN: + ParameterMetadata first = provider.next(part); + ParameterMetadata second = provider.next(part); + return builder.between(getComparablePath(root, part), first.getExpression(), second.getExpression()); + case AFTER: + case GREATER_THAN: + return builder.greaterThan(getComparablePath(root, part), provider.next(part, Comparable.class) + .getExpression()); + case GREATER_THAN_EQUAL: + return builder.greaterThanOrEqualTo(getComparablePath(root, part), provider.next(part, Comparable.class) + .getExpression()); + case BEFORE: + case LESS_THAN: + return builder.lessThan(getComparablePath(root, part), provider.next(part, Comparable.class).getExpression()); + case LESS_THAN_EQUAL: + return builder.lessThanOrEqualTo(getComparablePath(root, part), provider.next(part, Comparable.class) + .getExpression()); + case IS_NULL: + return path.isNull(); + case IS_NOT_NULL: + return path.isNotNull(); + case NOT_IN: + return path.in(provider.next(part, Collection.class).getExpression()).not(); + case IN: + return path.in(provider.next(part, Collection.class).getExpression()); + case STARTING_WITH: + case ENDING_WITH: + case CONTAINING: + case LIKE: + case NOT_LIKE: + Expression stringPath = getTypedPath(root, part); + Expression propertyExpression = upperIfIgnoreCase(stringPath); + Expression parameterExpression = upperIfIgnoreCase(provider.next(part, String.class).getExpression()); + Predicate like = builder.like(propertyExpression, parameterExpression); + return part.getType() == Type.NOT_LIKE ? like.not() : like; + case TRUE: + Expression truePath = getTypedPath(root, part); + return builder.isTrue(truePath); + case FALSE: + Expression falsePath = getTypedPath(root, part); + return builder.isFalse(falsePath); + case SIMPLE_PROPERTY: + ParameterMetadata expression = provider.next(part); + return expression.isIsNullParameter() ? path.isNull() : builder.equal(upperIfIgnoreCase(path), + upperIfIgnoreCase(expression.getExpression())); + case NEGATING_SIMPLE_PROPERTY: + return builder.notEqual(upperIfIgnoreCase(path), upperIfIgnoreCase(provider.next(part).getExpression())); + default: + throw new IllegalArgumentException("Unsupported keyword " + part.getType()); } } @@ -261,16 +261,24 @@ public class JpaQueryCreator extends AbstractQueryCreator, private Expression upperIfIgnoreCase(Expression expression) { switch (part.shouldIgnoreCase()) { - case ALWAYS: - Assert.state(canUpperCase(expression), "Unable to ignore case of " + expression.getJavaType().getName() - + " types, the property '" + part.getProperty().getSegment() + "' must reference a String"); - return (Expression) builder.upper((Expression) expression); - case WHEN_POSSIBLE: - if (canUpperCase(expression)) { + + case ALWAYS: + + Assert.state(canUpperCase(expression), "Unable to ignore case of " + expression.getJavaType().getName() + + " types, the property '" + part.getProperty().getSegment() + "' must reference a String"); return (Expression) builder.upper((Expression) expression); - } + + case WHEN_POSSIBLE: + + if (canUpperCase(expression)) { + return (Expression) builder.upper((Expression) expression); + } + + case NEVER: + default: + + return (Expression) expression; } - return (Expression) expression; } private boolean canUpperCase(Expression expression) { diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java index b41f29848..a3e89423e 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java @@ -34,8 +34,6 @@ import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.QueryHints; -import org.springframework.data.jpa.repository.support.DefaultJpaEntityMetadata; -import org.springframework.data.jpa.repository.support.JpaEntityMetadata; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; diff --git a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java index a678b6676..98035fd03 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java @@ -24,7 +24,6 @@ import javax.persistence.NamedStoredProcedureQueries; import javax.persistence.NamedStoredProcedureQuery; import javax.persistence.StoredProcedureParameter; -import org.springframework.data.jpa.repository.support.JpaEntityMetadata; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java index 1a2e3aa9c..597b6eb6b 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java @@ -19,6 +19,7 @@ import java.io.Serializable; import javax.persistence.metamodel.SingularAttribute; +import org.springframework.data.jpa.repository.query.JpaEntityMetadata; import org.springframework.data.repository.core.EntityInformation; /** diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupport.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupport.java index b62db08f8..d0cbe0e51 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupport.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupport.java @@ -21,6 +21,8 @@ import javax.persistence.EntityManager; import javax.persistence.metamodel.Metamodel; import org.springframework.data.domain.Persistable; +import org.springframework.data.jpa.repository.query.DefaultJpaEntityMetadata; +import org.springframework.data.jpa.repository.query.JpaEntityMetadata; import org.springframework.data.repository.core.support.AbstractEntityInformation; import org.springframework.util.Assert; diff --git a/src/main/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.java b/src/main/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.java index df12d35e2..29b75a725 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.java @@ -27,8 +27,8 @@ import javax.persistence.LockModeType; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.query.Jpa21Utils; import org.springframework.data.jpa.repository.query.JpaEntityGraph; -import org.springframework.data.jpa.util.Jpa21Utils; import org.springframework.data.querydsl.EntityPathResolver; import org.springframework.data.querydsl.QSort; import org.springframework.data.querydsl.QueryDslPredicateExecutor; diff --git a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 249f4dc3f..e289ebd3c 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -44,8 +44,8 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.query.Jpa21Utils; import org.springframework.data.jpa.repository.query.QueryUtils; -import org.springframework.data.jpa.util.Jpa21Utils; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java index 6c05718bf..07e756020 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/ExpressionBasedStringQueryUnitTests.java @@ -23,7 +23,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.data.jpa.repository.support.JpaEntityMetadata; /** * Unit tests for {@link ExpressionBasedStringQuery}. diff --git a/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java index c5d585316..d2d0fbfb8 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java @@ -42,8 +42,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.sample.User; import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.sample.UserRepository; -import org.springframework.data.jpa.repository.support.DefaultJpaEntityMetadata; -import org.springframework.data.jpa.repository.support.JpaEntityMetadata; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.data.repository.query.DefaultEvaluationContextProvider; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSourceUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSourceUnitTests.java index b4cced5ac..36f4d41f1 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSourceUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSourceUnitTests.java @@ -30,7 +30,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.data.jpa.domain.sample.User; -import org.springframework.data.jpa.repository.support.JpaEntityMetadata; import org.springframework.data.repository.query.Param; import org.springframework.util.ReflectionUtils; diff --git a/src/test/java/org/springframework/data/jpa/repository/support/DefaultJpaEntityMetadataUnitTest.java b/src/test/java/org/springframework/data/jpa/repository/support/DefaultJpaEntityMetadataUnitTest.java index b20022182..3c99ac06d 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/DefaultJpaEntityMetadataUnitTest.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/DefaultJpaEntityMetadataUnitTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.*; import javax.persistence.Entity; import org.junit.Test; +import org.springframework.data.jpa.repository.query.DefaultJpaEntityMetadata; /** * Unit tests for {@link DefaultJpaEntityMetadata}.