Benjamin M. (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5f1862a...
) *updated* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiOGI2YjJjZWIy...
) / Bug (
https://hibernate.atlassian.net/browse/HHH-14113?atlOrigin=eyJpIjoiOGI2Yj...
) HHH-14113 (
https://hibernate.atlassian.net/browse/HHH-14113?atlOrigin=eyJpIjoiOGI2Yj...
) Entity Graph attribute resolution not based on selected entity (
https://hibernate.atlassian.net/browse/HHH-14113?atlOrigin=eyJpIjoiOGI2Yj...
)
Change By: Benjamin M. (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5f1862a...
)
I was trying to fetch an entities association and have that fully initialized (will be
serialized to JSON):
{code:sql}SELECT u.groups FROM User u WHERE u.id = ?1{code}
Applying a Named/Ad Hoc Fetch Graph yields an Exception. E.g. for this Graph:
{code:java}EntityGraph<Group> eg = em.createEntityGraph(Group.class);
eg.addAttributeNodes("permissions");{code}
I get:
{quote}org.hibernate.QueryException: query specified join fetching, but the owner of the
fetched association was not present in the select list \[FromElement\{explicit,collection
join,fetch join,fetch non-lazy
properties,classAlias=u,role=com.example.assocFetchGraph.persistence.User.permissions,tableName=\{none},tableAlias=permission3_,origin=null,columns=\{,className=null}}]{quote}
That is because both classes have a `permissions` property. Otherwise I would get an error
saying the attribute was not found.
Expected behavior would be, that the Fetch Graph's attributes would be resolved
relative to Group, not User. (But the JPA spec doesn't seem to be very clear here).
I have created a reproducing example:
[
https://github.com/cptwunderlich/assocEntityGraphMRE|https://github.com/c...]
We had a discussion about this on Zulip #hibernate-user "EntityGraph
resolution"
I also created a StackOverflow question:
[
https://stackoverflow.com/questions/63015923/jpa-select-association-and-u...]
I provde an excerpt of the code here for your convenience:
{code:java}@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Permission.class)
@CollectionTable(name = "USERS_PERMISSIONS", joinColumns = @JoinColumn(name =
"uid"))
private Set<Permission> permissions = EnumSet.of(Permission.FOO);
@ManyToMany(fetch = FetchType.LAZY)
private Set<Group> groups = new HashSet<>();
}
@Entity
@NamedEntityGraph(name = Group.ENTITY_GRAPH,
attributeNodes = {
@NamedAttributeNode("permissions")
})
public class Group {
public static final String ENTITY_GRAPH = "group-with-permissions";
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Permission.class)
@CollectionTable(
name = "GROUPS_PERMISSIONS",
joinColumns = @JoinColumn(name = "gid")
)
private Set<Permission> permissions = EnumSet.noneOf(Permission.class);
}
// Query:
List res = em.createQuery("SELECT u.groups FROM User u WHERE u.id = ?1")
.setParameter(1, u.getId())
.setHint(GraphSemantic.FETCH.getJpaHintName(), em.getEntityGraph(Group.ENTITY_GRAPH))
.getResultList();{code}
Stack Trace is:
{noformat}java.lang.IllegalArgumentException: org.hibernate.QueryException: query
specified join fetching, but the owner of the fetched association was not present in the
select list [FromElement{explicit,collection join,fetch join,fetch non-lazy
properties,classAlias=u,role=com.example.assocFetchGraph.persistence.User.permissions,tableName={none},tableAlias=permission3_,origin=null,columns={,className=null}}]
[SELECT u.groups FROM com.example.assocFetchGraph.persistence.User u WHERE u.id = ?1]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
at
org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1542)
at org.hibernate.query.Query.getResultList(Query.java:165)
at
com.example.assocFetchGraph.AssocFetchGraphApplicationTests.fetchAssocWithNamedFetchGraph(AssocFetchGraphApplicationTests.java:48)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at
org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at
org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at
org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at
org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at
org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at
org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at
org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
at
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at
org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at
org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at
org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at
org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at
org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at
com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at
com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: org.hibernate.QueryException: query specified join fetching, but the owner of
the fetched association was not present in the select list
[FromElement{explicit,collection join,fetch join,fetch non-lazy
properties,classAlias=u,role=com.example.assocFetchGraph.persistence.User.permissions,tableName={none},tableAlias=permission3_,origin=null,columns={,className=null}}]
[SELECT u.groups FROM com.example.assocFetchGraph.persistence.User u WHERE u.id = ?1]
at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:220)
at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:78)
at
org.hibernate.query.internal.AbstractProducedQuery.makeQueryParametersForExecution(AbstractProducedQuery.java:1372)
at
org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1567)
at
org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)
... 65 more
Caused by: org.hibernate.QueryException: query specified join fetching, but the owner of
the fetched association was not present in the select list
[FromElement{explicit,collection join,fetch join,fetch non-lazy
properties,classAlias=u,role=com.example.assocFetchGraph.persistence.User.permissions,tableName={none},tableAlias=permission3_,origin=null,columns={,className=null}}]
at
org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:217)
at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:1026)
at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:794)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:689)
at
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:325)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:273)
at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276)
at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192)
... 71 more{noformat}
The repository also contains a test case where I JOIN FETCH permissions and that works.
Interestingly, in my actual code, I have and additional JOIN FETCH for a ManyToOne and I
get the above Exception for that additional property.
(
https://hibernate.atlassian.net/browse/HHH-14113#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-14113#add-comment?atlOrigin=ey...
)
Get Jira notifications on your phone! Download the Jira Cloud app for Android (
https://play.google.com/store/apps/details?id=com.atlassian.android.jira....
) or iOS (
https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100133- sha1:ead1094 )