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() {