クエリで結合フェッチが指定されましたが、フェッチされた関連付けの所有者が選択リストに存在しませんでした


83

2つの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 2013

2
あなたの場合の問題は、エンティティ全体(EntityChange)を選択するのではなく、いくつかの列だけを選択することだと思います。Fetch句は、ルートエンティティが選択されていて、マップされたコレクション/エンティティを結合して埋める場合にのみ意味があります。
アンディ・

回答:


117

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アノテーションが付けられたフィールドなどの関連付けの積極的な読み込みを強制するために も使用できます。
ロバートハント

53
うーん..私は同様の問題に直面していますが、n + 1の問題を回避するために結合フェッチを行う必要があります
Zhenya 2016年

4
@levgen、クエリの詳細はわかりませんが、カウントクエリに「フェッチ」を含めるべきではないことに注意してください。codingexplained.com/coding/java/spring-framework/...
笑顔

4
@levgenコードを見ずに手助けするのは難しい@Queryですが、アノテーション付きのSpring Dataを使用する場合は、フェッチとカウントに別々のクエリを指定できます:この質問を参照してください(Spring-Data FETCH JOIN with Pagingが機能していません)詳細については。
naXa 2017年

2
「フェッチ」を削除すると、N + 1の問題が発生し、アプリケーションのすべてがハングしました。このソリューションを誰にもお勧めしません。
AlkisMavridis20年1

20

結合フェッチが必要なため、フェッチを削除してもニーズは満たされません。

代わりに、カウントクエリを一緒に指定する必要があります。

結果をページ付けしていると仮定すると、以下はidをparamとして受け取り、指定した問題を引き起こすjpaクエリであり、2番目のクエリはそれにcountクエリを追加することでこれを解決します。

注:fk_fieldは、1対多のrlnを持つtableAの属性です。カウントクエリは結合フェッチを使用しません。

@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")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.