в запиті вказано приєднання, але власник отриманого зв’язку не був у списку вибору


83

Я вибираю два стовпці ідентифікатора, але отримую вказану помилку:

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), а лише кілька стовпців. Запропонувати вибір має сенс лише у тому випадку, якщо вибрано кореневу сутність, і ви хочете, щоб зіставлену колекцію / об'єкт заповнювали, приєднуючись до нього.
Енді,

Відповіді:


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
Женя

4
@levgen, я не знаю деталей вашого запиту, але майте на увазі, що запит підрахунку взагалі не повинен мати "отримання". codingexplained.com/coding/java/spring-framework/…
посмішка

4
@levgen Важко допомогти вам, не побачивши коду, але якщо трапляється, що ви використовуєте Spring Data з @Queryанотацією, ви можете вказати окремі запити для отримання та підрахунку: див. це запитання (Spring-Data FETCH JOIN with Paging не працює) для деталей.
naXa

2
Видалення "вибірки" призвело до проблеми N + 1 і призвело до зависання всього мого додатка. Не рекомендував би це рішення нікому.
Alkis Mavridis

20

Оскільки вам потрібно отримати приєднання, видалення отримання не відповідатиме вашим потребам.

Натомість вам слід зробити запит на підрахунок разом із ним.

Якщо припустити, що ви розміщуєте результат на сторінці, нижче наведено jpa-запит, який приймає id як параметр і спричинить вказану вами проблему, а другий запит вирішує це, додаючи до нього запит count.

Примітка: fk_fieldце атрибут таблиці 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")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.