쿼리가 조인 가져 오기를 지정했지만 가져온 연결의 소유자가 선택 목록에 없습니다.


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 절은 루트 엔터티가 선택되고 매핑 된 컬렉션 / 엔티티를 결합하여 채우려는 경우에만 의미가 있습니다.
andy

답변:


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으로 주석이 달린 필드와 같은 연관을 강제로로드하는 데 사용할 수도 있습니다.
Robert Hunt

49
흠 .. 나는 비슷한 문제에 직면하고있어,하지만 난 N + 1 문제를 방지하기 위해 가져 조인을 어떻게해야합니까
Zhenya

4
@levgen, 귀하의 쿼리에 대한 세부 정보를 모르지만 카운트 쿼리에는 "가져 오기"가 전혀 포함되지 않아야합니다. codingexplained.com/coding/java/spring-framework/...
미소

3
@levgen 코드를 보지 않고는 도움을주기가 어렵지만 @Query주석 과 함께 SpringData를 사용하는 경우 가져 오기 및 개수에 대해 별도의 쿼리를 지정할 수 있습니다. 이 질문을 참조하십시오 (Spring-Data FETCH JOIN with Paging이 작동하지 않음). 자세한 내용은.
naXa

2
"가져 오기"를 제거하면 N + 1 문제가 발생하여 응용 프로그램의 모든 것이 중단되었습니다. 이 솔루션을 누구에게도 권장하지 않습니다.
Alkis Mavridis

18

조인 가져 오기가 필요하므로 가져 오기를 제거하면 요구 사항을 충족 할 수 없습니다.

대신해야 할 일은 카운트 쿼리를 함께 지정하는 것입니다.

결과를 페이지로 나누고 있다고 가정하면 아래는 id를 매개 변수로 사용하고 지정한 문제를 일으키는 jpa 쿼리이며 두 번째 쿼리는 count 쿼리를 추가하여이를 해결합니다.

참고 : fk_field은 일대 다 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.