2016-06-23 5 views
1

У меня есть следующая гибернация объект:Hibernate предприятия с более чем два OneToMany полого

@Entity 
public class Customer { 

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private List<Address> addresses = new ArrayList<>(); 

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private List<Contact> contacts = new ArrayList<>(); 

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private List<Name> names = new ArrayList<>(); 

    // Many more, including a primary key 
} 

Запуск приложения, я получаю следующее исключение:

org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags 

Если удалить одну произвольный OneToMany ассоциации, или если я добавлю @Fetch(value = FetchMode.JOIN) в арбитражную ассоциацию OneToMany, все будет хорошо.

Является ли это ошибкой спящего режима, спящим ограничением, или что-то не так с моей сущностью? ТИА!

ответ

4

Это не ошибка. Это связано с тем, что Hibernate использует один select с соединением для извлечения всех данных. Hibernate может присоединиться к трем и более таблицам, но результат объединения будет иметь дубликаты, например, Address столбцов. Hibernate необходимо удалить дубликаты - это причина, почему работает Set.

Возможные обходные пути:

  • Используйте Set<Address> вместо List<Address>. Вы должны использовать Set для всех коллекций.
  • Использование ленивого выборка fetch = FetchType.LAZY
  • Использование @Fetch(value = FetchMode.SUBSELECT)

Некоторое дополнительное чтение:

A beginner’s guide to Hibernate Set and List behavior

Hibernate does not return distinct results for a query with outer join fetching enabled for a collection (even if I use the distinct keyword)?

+0

Без спящего режима я могу присоединиться к более чем двум таблицам. Это ограничение, что спящий режим не может присоединиться к трем таблицам? Он работает для меня с помощью FetchType.LAZY или с помощью FetchMode.SUBSELECT, но это может быть медленнее. Он не работает, используя 'Set' вместо' List'. – t777

+1

@ t777 Благодарим вас за принятие. Я добавляю некоторые ссылки. –

1

Попробуйте использовать:

@OneToMany 
@LazyCollection(value=LazyCollectionOption.TRUE) 
private Collection<Name> names = new ArrayList<>();