Skip to content

Commit 051a584

Browse files
committed
Minimal reproducible example
1 parent 4e81bf5 commit 051a584

31 files changed

+736
-0
lines changed

.gitignore

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
target/
2+
!**/src/main/**/target/
3+
!**/src/test/**/target/
4+
5+
### STS ###
6+
.apt_generated
7+
.classpath
8+
.factorypath
9+
.project
10+
.settings
11+
.springBeans
12+
.sts4-cache
13+
14+
### IntelliJ IDEA ###
15+
.idea
16+
*.iws
17+
*.iml
18+
*.ipr
19+
20+
### NetBeans ###
21+
/nbproject/private/
22+
/nbbuild/
23+
/dist/
24+
/nbdist/
25+
/.nb-gradle/
26+
build/
27+
!**/src/main/**/build/
28+
!**/src/test/**/build/
29+
30+
### VS Code ###
31+
.vscode/

README.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Spring Boot / Spring Data JPA Query Method Issue
2+
3+
The modules `spring-boot-3.1.1` and `spring-boot-3.1.2` contain test applications which are identical except for the Spring Boot / Spring Data JPA versions.
4+
5+
[`BaseArticleRepositoryCustomImpl.java`](spring-boot-3.1.1/src/main/java/org/devopsix/springdatajpa/BaseArticleRepositoryCustomImpl.java) contains a method utilizing JPA Criteria API for loading entities.
6+
In [`BaseArticleRepositoryTest.java`](spring-boot-3.1.1/src/test/java/org/devopsix/springdatajpa/BaseArticleRepositoryTest.java) this method is invoked.
7+
8+
## Spring Boot 3.1.1 (Spring Data JPA 3.1.1)
9+
10+
```
11+
mvn -f spring-boot-3.1.1/pom.xml verify
12+
```
13+
14+
Build succeeds.
15+
16+
## Spring Boot 3.1.2 (Spring Data JPA 3.1.2)
17+
18+
```
19+
mvn -f spring-boot-3.1.2/pom.xml verify
20+
```
21+
22+
Build fails for a test failure due to this exception:
23+
24+
```
25+
java.lang.AssertionError
26+
at org.hibernate.query.sqm.tree.domain.AbstractSqmPath.copyTo(AbstractSqmPath.java:61)
27+
at org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath.copy(SqmEntityValuedSimplePath.java:47)
28+
at org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath.copy(SqmEntityValuedSimplePath.java:21)
29+
at org.hibernate.query.sqm.tree.domain.AbstractSqmPath.copyTo(AbstractSqmPath.java:67)
30+
at org.hibernate.query.sqm.tree.domain.AbstractSqmFrom.copyTo(AbstractSqmFrom.java:130)
31+
at org.hibernate.query.sqm.tree.domain.AbstractSqmQualifiedJoin.copyTo(AbstractSqmQualifiedJoin.java:39)
32+
at org.hibernate.query.sqm.tree.domain.SqmSetJoin.copy(SqmSetJoin.java:74)
33+
at org.hibernate.query.sqm.tree.domain.SqmSetJoin.copy(SqmSetJoin.java:32)
34+
at org.hibernate.query.sqm.tree.domain.AbstractSqmFrom.copyTo(AbstractSqmFrom.java:134)
35+
at org.hibernate.query.sqm.tree.from.SqmRoot.copyTo(SqmRoot.java:93)
36+
at org.hibernate.query.sqm.tree.from.SqmRoot.copy(SqmRoot.java:87)
37+
at org.hibernate.query.sqm.tree.from.SqmFromClause.<init>(SqmFromClause.java:40)
38+
at org.hibernate.query.sqm.tree.from.SqmFromClause.copy(SqmFromClause.java:46)
39+
at org.hibernate.query.sqm.tree.select.SqmQuerySpec.copy(SqmQuerySpec.java:101)
40+
at org.hibernate.query.sqm.tree.select.SqmQuerySpec.copy(SqmQuerySpec.java:56)
41+
at org.hibernate.query.sqm.tree.select.SqmSelectStatement.copy(SqmSelectStatement.java:131)
42+
at org.hibernate.query.sqm.tree.select.SqmSelectStatement.copy(SqmSelectStatement.java:42)
43+
at org.hibernate.query.sqm.internal.QuerySqmImpl.<init>(QuerySqmImpl.java:226)
44+
at org.hibernate.internal.AbstractSharedSessionContract.createCriteriaQuery(AbstractSharedSessionContract.java:1343)
45+
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:1304)
46+
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:120)
47+
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
48+
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
49+
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)
50+
at jdk.proxy2/jdk.proxy2.$Proxy103.createQuery(Unknown Source)
51+
at org.devopsix.springdatajpa.BaseArticleRepositoryCustomImpl.search(BaseArticleRepositoryCustomImpl.java:30)
52+
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
53+
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
54+
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:288)
55+
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
56+
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
57+
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516)
58+
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
59+
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628)
60+
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
61+
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:168)
62+
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
63+
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
64+
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
65+
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391)
66+
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
67+
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
68+
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
69+
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
70+
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:164)
71+
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
72+
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
73+
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
74+
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244)
75+
at jdk.proxy2/jdk.proxy2.$Proxy110.search(Unknown Source)
76+
at org.devopsix.springdatajpa.BaseArticleRepositoryTest.test(BaseArticleRepositoryTest.java:15)
77+
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
78+
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
79+
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
80+
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
81+
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
82+
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
83+
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
84+
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
85+
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
86+
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
87+
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
88+
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
89+
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
90+
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
91+
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
92+
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
93+
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
94+
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
95+
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
96+
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
97+
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
98+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
99+
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
100+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
101+
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
102+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
103+
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
104+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
105+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
106+
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
107+
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
108+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
109+
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
110+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
111+
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
112+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
113+
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
114+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
115+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
116+
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
117+
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
118+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
119+
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
120+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
121+
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
122+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
123+
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
124+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
125+
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
126+
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
127+
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
128+
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
129+
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
130+
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
131+
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
132+
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
133+
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
134+
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
135+
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
136+
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
137+
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
138+
at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:50)
139+
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
140+
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
141+
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122)
142+
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
143+
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
144+
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
145+
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
146+
```

pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>org.devopsix</groupId>
7+
<artifactId>spring-data-jpa-query-method-issue</artifactId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
<packaging>pom</packaging>
10+
11+
<modules>
12+
<module>spring-boot-3.1.1</module>
13+
<module>spring-boot-3.1.2</module>
14+
</modules>
15+
</project>

spring-boot-3.1.1/pom.xml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.springframework.boot</groupId>
9+
<artifactId>spring-boot-starter-parent</artifactId>
10+
<version>3.1.1</version>
11+
<relativePath/>
12+
</parent>
13+
14+
<groupId>org.devopsix.spring-data-jpa-query-method-issue</groupId>
15+
<artifactId>spring-boot-3.1.1</artifactId>
16+
17+
<properties>
18+
<java.version>18</java.version>
19+
</properties>
20+
21+
<dependencies>
22+
<dependency>
23+
<groupId>org.springframework.boot</groupId>
24+
<artifactId>spring-boot-starter-web</artifactId>
25+
</dependency>
26+
<dependency>
27+
<groupId>org.springframework.boot</groupId>
28+
<artifactId>spring-boot-starter-data-jpa</artifactId>
29+
</dependency>
30+
<dependency>
31+
<groupId>org.hsqldb</groupId>
32+
<artifactId>hsqldb</artifactId>
33+
<scope>runtime</scope>
34+
</dependency>
35+
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-configuration-processor</artifactId>
39+
<optional>true</optional>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.springframework.boot</groupId>
43+
<artifactId>spring-boot-starter-test</artifactId>
44+
<scope>test</scope>
45+
</dependency>
46+
</dependencies>
47+
48+
<build>
49+
<plugins>
50+
<plugin>
51+
<groupId>org.springframework.boot</groupId>
52+
<artifactId>spring-boot-maven-plugin</artifactId>
53+
</plugin>
54+
55+
<plugin>
56+
<groupId>org.apache.maven.plugins</groupId>
57+
<artifactId>maven-surefire-plugin</artifactId>
58+
<configuration>
59+
<skipTests>true</skipTests>
60+
</configuration>
61+
</plugin>
62+
63+
<plugin>
64+
<groupId>org.apache.maven.plugins</groupId>
65+
<artifactId>maven-failsafe-plugin</artifactId>
66+
<configuration>
67+
<includes>
68+
<!-- Include integration tests within integration-test phase. -->
69+
<include>**/*Test.java</include>
70+
</includes>
71+
</configuration>
72+
</plugin>
73+
</plugins>
74+
</build>
75+
76+
</project>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.devopsix.springdatajpa;
2+
3+
import jakarta.persistence.Entity;
4+
5+
@Entity
6+
public class Account extends BaseEntity {
7+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.devopsix.springdatajpa;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.OneToMany;
5+
6+
import java.util.Set;
7+
8+
@Entity
9+
public abstract class Article<C extends ArticleCustomization<? extends Article<C>>> extends BaseArticle {
10+
11+
@OneToMany(mappedBy = "article", targetEntity = ArticleCustomization.class)
12+
private Set<C> customizations;
13+
14+
public Set<C> getCustomizations() {
15+
return customizations;
16+
}
17+
18+
public void setCustomizations(Set<C> customizations) {
19+
this.customizations = customizations;
20+
}
21+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.devopsix.springdatajpa;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.Inheritance;
5+
import jakarta.persistence.JoinColumn;
6+
import jakarta.persistence.ManyToOne;
7+
8+
import static jakarta.persistence.FetchType.LAZY;
9+
import static jakarta.persistence.InheritanceType.SINGLE_TABLE;
10+
11+
@Entity
12+
@Inheritance(strategy = SINGLE_TABLE)
13+
public abstract class ArticleCustomization<A extends Article<? extends ArticleCustomization<A>>> extends BaseEntity {
14+
15+
@ManyToOne(fetch = LAZY)
16+
@JoinColumn(name = "account_id")
17+
private Account account;
18+
19+
@ManyToOne(fetch = LAZY, targetEntity = Article.class)
20+
@JoinColumn(name = "article_id")
21+
private A article;
22+
23+
public Account getAccount() {
24+
return account;
25+
}
26+
27+
public void setAccount(Account account) {
28+
this.account = account;
29+
}
30+
31+
public A getArticle() {
32+
return article;
33+
}
34+
35+
public void setArticle(A article) {
36+
this.article = article;
37+
}
38+
}
39+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.devopsix.springdatajpa;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.Inheritance;
5+
6+
import static jakarta.persistence.InheritanceType.SINGLE_TABLE;
7+
8+
@Entity
9+
@Inheritance(strategy = SINGLE_TABLE)
10+
public abstract class BaseArticle extends BaseEntity {
11+
}

0 commit comments

Comments
 (0)