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


82

我正在选择两个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]

一些代码:

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";

如何解决错误,我在做什么错?


6
对于我这个问题的未来搜索者,在我的情况下,我加入了一个非惰性属性。当我删除加入条款时,它就解决了。
merveotesi

2
我认为在您的情况下,问题在于您没有选择整个实体(EntityChange),而是仅选择了几列。如果选择了根实体,并且您希望通过联接来填充映射的集合/实体,则Fetch子句才有意义。
安迪

Answers:


116

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

String hql = " select ec.id as entityChangeId, r.id as revisionId from EntityChange as ec " + 
        " join ec.revision as r " + ...

正如错误消息告诉您的那样,join fetch这里没有意义,因为它是一种性能提示,会迫使人们急切地加载集合。


4
只是为了说明join fetch起见, 它也可以用于强制加载关联,例如用@ManyToOne注释的字段,而不仅仅是集合。
罗伯特·亨特

49
嗯..我正面临类似的问题,但我确实需要进行联接获取以避免n + 1问题
Zhenya

4
@levgen,我不知道您的查询的详细信息,但是请记住,计数查询根本不应该具有“访存”功能。encodingexplained.com/coding/java/spring-framework/…–
微笑

3
@levgen很难在没有代码的情况下为您提供帮助,但是如果碰巧您使用带有@Query注解的Spring数据,则可以为获取和计数指定单独的查询:请参阅此问题(带有分页的Spring-Data FETCH JOIN无法正常工作)有关详细信息。
naXa

2
删除“提取”导致我遇到了N + 1问题,并导致应用程序中的所有内容挂起。不会向任何人推荐此解决方案。
Alkis Mavridis

18

由于您需要联接提取,因此删除提取将无法满足您的需求。

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

假设您要对结果进行分页,下面是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")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.