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

Hibernate 查询指定了联接提取,但提取的关联的所有者不在选择列表中,hibernate,join,fetch,Hibernate,Join,Fetch,我正在选择两个id列,但指定了get错误: 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,clas

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

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]
org.hibernate.QueryException:*查询指定了联接获取,但获取的关联的所有者不在选择列表中**
[FromElement{explicit,非集合联接,fetch联接,fetch非惰性属性,classAlias=r,role=null,tableName=REVISION,tableAlias=revision1,origin=ENTITY\u CHANGED\u IN\u REVISION entitychan0\u0,columns={entitychan0\u0.REV\u ID,className=ru.csbi.registry.domain.envers.REVISION}][从ru.csbi.registry.domain.envers.EntityChange中选择ec.id作为entityChangeId,r.id作为revisionId作为ec内部连接获取ec.revision作为r,其中ec.groupEntityId=:groupEntityId和ec.groupName=:groupName和r.timestamp<:entityDateFrom和r.timestamp>:entityDateTo和(ec.revisionType in(0,5,1,4,2)和not(ec.otherGroupEntityModified=false和ec.thisGroupEntityModified=true和ec.rowDataModified=false和ec.collectionOfNotGroupEntityModified=false))按ec.id分组,r.id有计数(*)>:按r.id说明开始顺序]
一些代码:

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";
String hql=“选择ec.id作为entityChangeId,从EntityChange中选择r.id作为修订id作为ec”+
“内部联接获取ec.revision作为r”+
“其中ec.groupEntityId=:groupEntityId”+
“和ec.groupName=:groupName”+
“和r.timestamp<:entityDateFrom”+
“和r.timestamp>:entityDateTo”+
“和(”+
“ec.revisionType输入(“+
RevisionType.ADD.getRepresentation()+“,”+
RevisionType.ONLY_DATA_PROPERTY_MOD.getRepresentation()+“,”+
修订类型。集合和属性都是MOD.getRepresentation()+“,”+
RevisionType.ONLY_COLLECTION_PROPERTY_MOD.getRepresentation()+“,”+
RevisionType.DEL.getRepresentation()的+
" ) " +
“而不是(”+
“ec.otherGroupEntityModified=false和”+
“ec.thisGroupEntityModified=真且”+
“ec.rowDataModified=false和”+
“ec.collectionOfNotGroupEntityModified=false”+
"  ) " +
"     ) " +
“按ec.id、r.id分组”+
“具有计数(*)>:开始”+
“按r.id描述订购”;

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

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


正如错误消息告诉您的那样,
join-fetch
在这里没有意义,因为它是一个性能提示,强制急切地加载集合。

当您需要join-fetch时,删除fetch将无法满足您的需要

您应该做的是指定一个计数查询

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

注意:
fk_字段
是表A中具有一对多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")

您必须将相关项目列放入selection子句中

select ec.id as entityChangeId, r.id as revisionId, **r.revision** from EntityChange as ec " +
        " inner join fetch ec.revision as r " +

对于这个问题的未来搜索者,在我的情况下,我加入了一个非惰性属性。当我删除连接子句时,问题就解决了。我认为在您的情况下,问题在于您没有选择整个实体(EntityChange)但是只有几列。Fetch子句才有意义,如果选择了根实体,并且您希望通过加入它来填充映射的集合/实体。只是澄清一下,
join Fetch
还可以用于强制加载关联,例如用@ManyToOne注释的字段,而不仅仅是collections。嗯……我面临一个sim卡ilar问题,但我确实需要执行联接获取以避免n+1problem@levgen,我不知道您的查询的详细信息,但请记住,count查询不应具有“fetch”@levgen如果没有代码,很难帮助您,但是如果您使用带有
@Query
注释的Spring数据,那么您可以为获取和计数指定单独的查询:有关详细信息,请参阅。删除“获取”导致我出现N+1问题,并导致我的应用程序中的所有内容挂起。不会向任何人推荐此解决方案。这是正确的答案,实际上:)是的,如果要继续获取并避免N+1,这是正确的答案。谢谢!是的,这是正确的答案,谢谢。
select ec.id as entityChangeId, r.id as revisionId, **r.revision** from EntityChange as ec " +
        " inner join fetch ec.revision as r " +