查询指定的连接提取,但提取的关联的所有者不在选择列表中

Vya*_*lav 67 hibernate join fetch

我正在选择两个id列但指定了错误:

org.hibernate.QueryException: **query specified join fetching, but the owner of the fetched association was not present in the select list** 

[FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=r,role=null,tableName=REVISIONS,tableAlias=revision1_,origin=ENTITY_CHANGED_IN_REVISION entitychan0_,columns={entitychan0_.REV_ID ,className=ru.csbi.registry.domain.envers.Revision}}] [ select ec.id as entityChangeId, r.id as revisionId from ru.csbi.registry.domain.envers.EntityChange as ec  inner join fetch ec.revision as r  where ec.groupEntityId = :groupEntityId and ec.groupName = :groupName  and r.timestamp < :entityDateFrom  and r.timestamp > :entityDateTo  and (        ec.revisionType in (0, 5, 1, 4, 2 )       and not ( ec.otherGroupEntityModified = false and ec.thisGroupEntityModified = true and ec.rowDataModified = false and ec.collectionOfNotGroupEntityModified = false   )      )  group by ec.id, r.id  having count(*) > :start order by r.id desc]
Run Code Online (Sandbox Code Playgroud)

一些代码:

String hql = " select ec.id as entityChangeId, r.id as revisionId from EntityChange as ec " +
            " inner join fetch ec.revision as r " +
            " where ec.groupEntityId = :groupEntityId" +
            " and ec.groupName = :groupName " +
            " and r.timestamp < :entityDateFrom " +
            " and r.timestamp > :entityDateTo " +
            " and ( " +
            "       ec.revisionType in (" + 
                        RevisionType.ADD.getRepresentation() + ", " + 
                        RevisionType.ONLY_DATA_PROPERTY_MOD.getRepresentation() + ", " +
                        RevisionType.BOTH_COLLECTION_AND_PROPERTY_MOD.getRepresentation() + ", " +
                        RevisionType.ONLY_COLLECTION_PROPERTY_MOD.getRepresentation() + ", " +
                        RevisionType.DEL.getRepresentation() +
                    " ) " +
            "     and not ( "+
                    "ec.otherGroupEntityModified = false and " +
                    "ec.thisGroupEntityModified = true and " +
                    "ec.rowDataModified = false and " +
                    "ec.collectionOfNotGroupEntityModified = false " +
                "  ) " +
            "     ) " +
            " group by ec.id, r.id " +
            " having count(*) > :start" +
            " order by r.id desc";
Run Code Online (Sandbox Code Playgroud)

如何修复错误以及我做错了什么?

axt*_*avt 105

使用常规join而不是join fetch(顺便说一句,inner默认情况下):

String hql = " select ec.id as entityChangeId, r.id as revisionId from EntityChange as ec " + 
        " join ec.revision as r " + ...
Run Code Online (Sandbox Code Playgroud)

正如错误消息告诉你的那样,join fetch这里没有意义,因为它是一个性能提示,迫使急切加载集合.

  • 嗯..我面临着类似的问题,但我确实需要进行连接提取以避免n + 1问题 (32认同)
  • 删除“fetch”导致我遇到 N+1 问题,并导致应用程序中的所有内容挂起。不会向任何人推荐此解决方案。 (7认同)
  • 为了澄清,`join fetch`也可以用来强制加载一个关联,例如用@ManyToOne注释的字段,而不仅仅是集合. (4认同)
  • @levgen在没有看到代码的情况下很难帮助你,但是如果你使用带有`@Query`注释的Spring Data,那么你可以指定用于获取和计数的单独查询:参见[this question(Spring-Data FETCH JOIN with分页不起作用)](/sf/ask/1508463631/)了解详细信息. (3认同)
  • 这不是问题的解决方案,因为作者希望使用连接获取来可能避免 n+1 问题。 (3认同)
  • @levgen,我不知道您的查询的详细信息,但请记住,count查询不应该有"fetch".https://codingexplained.com/coding/java/spring-framework/fetch-query-not-working-spring-data-jpa-pageable#comment-293535 (2认同)
  • 使用下面的答案(添加计数查询)。此解决方案会导致 n+1 问题。 (2认同)

myk*_*key 33

由于您需要 join fetch,因此删除 fetch 将无法满足您的需求。

您应该做的是与其一起指定计数查询。

假设您正在对结果进行分页,下面是 jpa 查询,它将 id 作为参数并会导致您指定的问题,第二个查询通过向其中添加计数查询来解决此问题。

注意:fk_field是tableA中具有一对多rln的属性。计数查询不使用连接提取。

@Query(value = "from TableA a LEFT JOIN FETCH a.fk_field where a.id = :id") 

@Query(value = "from TableA a LEFT JOIN FETCH a.fk_field where a.id = :id", 
  countQuery = " select  count(a) from TableA a left join a.fk_field where a.id = :id")
Run Code Online (Sandbox Code Playgroud)

  • 实际上,这是正确的答案:) (2认同)
  • 是的,如果您想保留 FETCH 并避免 n+1,这是正确的答案。谢谢! (2认同)

Art*_*sun 11

与OP的特定查询无关,但对我来说,query specified join fetching, but the owner of the fetched association was not present in the select list由于不正确而引发了相同的错误JOIN FETCH嵌套关系的语法不正确,引发了同样的错误,它必须通过别名引用,而我直观地尝试通过完整路径引用它。

坏:(导致not present in the select list错误)

SELECT * FROM TableA a
JOIN FETCH a.relationB
JOIN FETCH a.relationB.relationC
Run Code Online (Sandbox Code Playgroud)

干得好!)

SELECT * FROM TableA a
JOIN FETCH a.relationB AS b
JOIN FETCH b.relationC
Run Code Online (Sandbox Code Playgroud)

希望对某人有帮助