Wybieram dwie kolumny identyfikatora, ale został określony błąd:
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]
Jakiś kod:
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";
Jak naprawić błąd i co robię źle?
Odpowiedzi:
Użyj zwykłego
join
zamiastjoin fetch
(nawiasem mówiąc, jest toinner
domyślne):String hql = " select ec.id as entityChangeId, r.id as revisionId from EntityChange as ec " + " join ec.revision as r " + ...
Jak mówi komunikat o błędzie,
join fetch
nie ma tu sensu, ponieważ jest to wskazówka dotycząca wydajności, która wymusza chętne ładowanie kolekcji.źródło
join fetch
może być również używany do wymuszania gorliwego ładowania skojarzenia, takiego jak pole z adnotacją @ManyToOne, a nie tylko kolekcji.@Query
adnotacją, możesz określić oddzielne zapytania do pobierania i liczenia: zobacz to pytanie (Spring-Data FETCH JOIN with Paging nie działa) dla szczegółów.Ponieważ potrzebujesz dołączenia do pobierania, usunięcie pobierania nie spełni twoich potrzeb.
Zamiast tego powinieneś podać razem z nim zapytanie liczące.
Zakładając, że paginujesz wynik, poniżej znajduje się zapytanie jpa, które przyjmuje id jako parametr i spowoduje problem, który podałeś, a drugie zapytanie rozwiązuje go, dodając do niego zapytanie count.
Uwaga:
fk_field
to atrybut w tabeli A, który ma rln jeden do wielu. Zapytanie zliczające nie korzysta z pobierania sprzężenia.@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")
źródło