Hibernate fetch join -> не может получить несколько пакетов - PullRequest
6 голосов
/ 24 августа 2011

Проблема в том, что у меня есть две сумки в моей сущности, которые я хотел бы отобразить в моем интерфейсе jsf (пружина сзади, поэтому не ленивая загрузка).Поэтому мне нужно с нетерпением получить их, чтобы отобразить информацию в виде списка:

  • Точка 1 (Метка 1, Метка 2) (Тег1 ... Тег n)
  • Пункт2 (Метка 3, Метка 4) (Tag1 ... Tag n)

Перевод обоих списков в нетерпение не сработал.Так что я попытал счастья с помощью соединения.Это позволило мне получить один список, но когда я добавил второй список, я получил известную ошибку «невозможно получить несколько пакетов».

Может ли Hibernate обрабатывать два соединения извлечения в запросе?

public class PointOfInterest
 @OneToMany(mappedBy="poi")
private List<PointOfInterestLabel> labels = new ArrayList<PointOfInterestLabel>();

@ManyToMany
private List<Tag> tags = new ArrayList<Tag>();

Мое соединение извлечения:

SELECT DISTINCT p from PointOfInterest p 
        left join fetch p.labels 
        left join fetch p.tags WHERE p.figure = :figure

При запуске создание моей фабрики спящего режима завершается неудачно с помощью:

Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
    at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94)
    at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:123)
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98)
    at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:557)
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:422)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
    ... 55 more

Ответы [ 3 ]

6 голосов
/ 24 августа 2011

Ответ: нет.С этим не справиться.Вот что он говорит.

Для типов значений (составной элемент) это даже не сработает, потому что вы не получаете информацию о том, что на самом деле принадлежит одному и тому же элементу сумки.

Обычноэто даже не имеет смысла.Если вы запросите таблицу и получите 10 записей в начальной таблице, 10 в первой сумке и еще 10 во второй сумке, вы получите 1000 записей только для создания этих 30 объектов в памяти.Представьте себе количество записей, когда в каждой таблице будет 100 записей (подсказка: 1 000 000 вместо 300) и когда вы выбираете, присоединитесь к другой сумке (подсказка: 100 000 000 вместо 400) ...

Кстати:выборка из соединения может привести к странным последствиям и проблемам, и ее следует избегать, если вы точно не знаете, что делаете.

1 голос
/ 04 сентября 2012

Вместо использования Set можно разделить запрос и загрузить объекты в разные запросы.
Например,

    From PointOfInterest p left join fetch p.labels WHERE p.figure = :figure
    From PointOfInterest p left join fetch p.tags WHERE p.figure = :figure            

Пожалуйста, обратитесь ссылка

0 голосов
/ 15 ноября 2018

Вы не можете иметь 2 1-n eager-join (или HQL fetch-joins) в одном запросе.

Если вы присоединяетесь к таблице 1-n и существует 10 совпадений строк, всеобщие столбцы не-N объектов дублируются для каждой строки.

Если он возвращает 10 строк, он должен решить, какой 1-n вызвал дополнительные строки.Что, технически, может основываться на ключах соединения - если ключи соединения являются уникальными первичными ключами.Но это исключение указывает на то, что спящий не может сказать.

...