diff --git a/ci/pipeline.properties b/ci/pipeline.properties index 57e4868d49..1ab126263d 100644 --- a/ci/pipeline.properties +++ b/ci/pipeline.properties @@ -1,18 +1,19 @@ # Java versions -java.main.tag=17.0.3_7-jdk +java.main.tag=17.0.4.1_1-jdk-focal # Docker container images - standard docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag} # Supported versions of MongoDB -docker.mongodb.4.4.version=4.4.12 -docker.mongodb.5.0.version=5.0.6 +docker.mongodb.4.4.version=4.4.17 +docker.mongodb.5.0.version=5.0.13 +docker.mongodb.6.0.version=6.0.2 # Supported versions of Redis docker.redis.6.version=6.2.6 # Supported versions of Cassandra -docker.cassandra.3.version=3.11.12 +docker.cassandra.3.version=3.11.14 # Docker environment settings docker.java.inside.basic=-v $HOME:/tmp/jenkins-home diff --git a/pom.xml b/pom.xml index 5ba0fde025..48bec13dc6 100644 --- a/pom.xml +++ b/pom.xml @@ -104,7 +104,7 @@ eclipselink-next - 4.0.0-RC2 + 4.0.0 diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/aot/JpaRuntimeHints.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/aot/JpaRuntimeHints.java similarity index 75% rename from spring-data-jpa/src/main/java/org/springframework/data/jpa/aot/JpaRuntimeHints.java rename to spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/aot/JpaRuntimeHints.java index a8026d6eb2..65bb6e357e 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/aot/JpaRuntimeHints.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/aot/JpaRuntimeHints.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jpa.aot; +package org.springframework.data.jpa.repository.aot; import java.util.Arrays; @@ -24,15 +24,20 @@ import org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.support.QuerydslJpaPredicateExecutor; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.querydsl.QuerydslUtils; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** + * Runtime hints for JPA AOT processing. + * * @author Christoph Strobl * @since 3.0 */ -public class JpaRuntimeHints implements RuntimeHintsRegistrar { +class JpaRuntimeHints implements RuntimeHintsRegistrar { @Override public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { @@ -49,9 +54,10 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) .withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS)); hints.reflection().registerTypes(Arrays.asList( // - TypeReference.of(AuditingBeanFactoryPostProcessor.class), // - TypeReference.of(AuditingEntityListener.class)), - hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS)); + TypeReference.of(AuditingBeanFactoryPostProcessor.class), // + TypeReference.of(AuditingEntityListener.class)), + hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS)); } hints.reflection().registerType(TypeReference.of(SimpleJpaRepository.class), @@ -59,5 +65,12 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) // needs to present for evaluating default attribute values in JpaQueryMethod hints.reflection().registerType(Query.class, hint -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); + + if (QuerydslUtils.QUERY_DSL_PRESENT) { + + hints.reflection().registerType(QuerydslJpaPredicateExecutor.class, + hint -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS) + .onReachableType(QuerydslPredicateExecutor.class)); + } } } diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java index e06e6abb0f..4f4317f77d 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigExtension.java @@ -46,13 +46,13 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.dao.DataAccessException; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; -import org.springframework.data.aot.AotRepositoryContext; -import org.springframework.data.aot.RepositoryRegistrationAotProcessor; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.support.DefaultJpaContext; import org.springframework.data.jpa.repository.support.EntityManagerBeanDefinitionRegistrarPostProcessor; import org.springframework.data.jpa.repository.support.JpaEvaluationContextExtension; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; +import org.springframework.data.repository.aot.AotRepositoryContext; +import org.springframework.data.repository.aot.RepositoryRegistrationAotProcessor; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport; import org.springframework.data.repository.config.RepositoryConfigurationSource; diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java index cdd49c6241..f3807f9a4e 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java @@ -87,6 +87,7 @@ public abstract class QueryUtils { private static final String SIMPLE_COUNT_VALUE = "$2"; private static final String COMPLEX_COUNT_VALUE = "$3 $6"; private static final String COMPLEX_COUNT_LAST_VALUE = "$6"; + private static final String FETCH_COMING_AFTER_JOIN_PART = "(?iu)(?<=join)(\\s*fetch\\s*)"; private static final String ORDER_BY_PART = "(?iu)\\s+order\\s+by\\s+.*"; private static final Pattern ALIAS_MATCH; @@ -601,6 +602,8 @@ public static String createCountQueryFor(String originalQuery, @Nullable String countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, countProjection)); } + countQuery = countQuery.replaceAll(FETCH_COMING_AFTER_JOIN_PART, " "); + return countQuery.replaceFirst(ORDER_BY_PART, ""); } diff --git a/spring-data-jpa/src/main/resources/META-INF/spring/aot.factories b/spring-data-jpa/src/main/resources/META-INF/spring/aot.factories index 4363dcaeb8..50d5fc795e 100644 --- a/spring-data-jpa/src/main/resources/META-INF/spring/aot.factories +++ b/spring-data-jpa/src/main/resources/META-INF/spring/aot.factories @@ -1,2 +1,2 @@ org.springframework.aot.hint.RuntimeHintsRegistrar=\ - org.springframework.data.jpa.aot.JpaRuntimeHints + org.springframework.data.jpa.repository.aot.JpaRuntimeHints diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/aot/JpaRuntimeHintsUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/aot/JpaRuntimeHintsUnitTests.java similarity index 94% rename from spring-data-jpa/src/test/java/org/springframework/data/jpa/aot/JpaRuntimeHintsUnitTests.java rename to spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/aot/JpaRuntimeHintsUnitTests.java index c992375198..c457ffcf80 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/aot/JpaRuntimeHintsUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/aot/JpaRuntimeHintsUnitTests.java @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jpa.aot; +package org.springframework.data.jpa.repository.aot; import static org.assertj.core.api.AssertionsForClassTypes.*; -import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection; +import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.*; import org.junit.jupiter.api.Test; + import org.springframework.aot.hint.RuntimeHints; import org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect; import org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor; @@ -26,6 +27,8 @@ import org.springframework.data.jpa.util.HidingClassLoader; /** + * Unit tests for {@link JpaRuntimeHints}. + * * @author Christoph Strobl */ class JpaRuntimeHintsUnitTests { diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryRegistrationAotProcessorUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryRegistrationAotProcessorUnitTests.java index 5204de044c..7b2ade3424 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryRegistrationAotProcessorUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryRegistrationAotProcessorUnitTests.java @@ -31,8 +31,9 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.data.aot.AotRepositoryContext; +import org.springframework.data.repository.aot.AotRepositoryContext; import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.javapoet.ClassName; /** * @author Christoph Strobl @@ -42,7 +43,7 @@ class JpaRepositoryRegistrationAotProcessorUnitTests { @Test // GH-2628 void aotProcessorMustNotRegisterDomainTypes() { - GenerationContext ctx = new DefaultGenerationContext(new ClassNameGenerator(Object.class), + GenerationContext ctx = new DefaultGenerationContext(new ClassNameGenerator(ClassName.OBJECT), new InMemoryGeneratedFiles()); new JpaRepositoryConfigExtension.JpaRepositoryRegistrationAotProcessor() @@ -59,7 +60,7 @@ public Set> getResolvedTypes() { @Test // GH-2628 void aotProcessorMustNotRegisterAnnotations() { - GenerationContext ctx = new DefaultGenerationContext(new ClassNameGenerator(Object.class), + GenerationContext ctx = new DefaultGenerationContext(new ClassNameGenerator(ClassName.OBJECT), new InMemoryGeneratedFiles()); new JpaRepositoryConfigExtension.JpaRepositoryRegistrationAotProcessor() diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/DefaultQueryUtilsUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/DefaultQueryUtilsUnitTests.java index 828f8a835b..3de3a010f7 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/DefaultQueryUtilsUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/DefaultQueryUtilsUnitTests.java @@ -40,6 +40,7 @@ * @author Grégoire Druant * @author Mohammad Hewedy * @author Greg Turnquist + * @author Vladislav Yukharin */ class DefaultQueryUtilsUnitTests { @@ -224,6 +225,13 @@ void doesNotPrefixSortsIfFunction() { .isThrownBy(() -> applySorting("select p from Person p", sort, "p")); } + @Test // GH-2348 + void removesFetchPartInJoinFetchClauseInGeneratedCountQueryIfPresent() { + + assertCountQuery("select u from User u left outer join fetch u.roles r left outer JOIN FETCH u.accounts a", + "select count(u) from User u left outer join u.roles r left outer JOIN u.accounts a"); + } + @Test // DATAJPA-377 void removesOrderByInGeneratedCountQueryFromOriginalQueryIfPresent() {