JPA - 使用Root和Join在字段上进行join fetch

3

我有这些类,字段总是懒加载。

public class Book {
     @ManyToOne(fetch = FetchType.LAZY)
     private Publication publication;

     @OneToMany(fetch = FetchType.LAZY)
     private List<Author> authors;

     @OneToMany(fetch = FetchType.LAZY)
     private List<Genre> genres;
}

public class Publication{
     @OneToMany(fetch = FetchType.LAZY)
     private List<Founder> founders;

}

我想要实现的是对一个联接获取进行联接获取。在HQL中,代码如下:

FROM Book b LEFT JOIN b.authors LEFT JOIN b.genres LEFT JOIN b.publication p LEFT JOIN p.founders

这是我目前尝试过的,但它并没有起作用:
Root<Book> root ...
Join<Book, Publication> publication = root.join("publication");
publication.fetch("founders");
root.fetch("authors");
root.fetch("genres");

以下是异常的原因:

Caused by: javax.persistence.PersistenceException: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:588)
    at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:336)
    at org.hibernate.jpa.criteria.compile.CriteriaCompiler.compile(CriteriaCompiler.java:147)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:736)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
1个回答

6

JPA规范指出:

实现此规范的应用程序不需要支持多级联接。使用多级联接的应用程序将无法移植。

尝试减少查询中的联接,并稍后初始化数据(在数据选择后)。 您可以在同一事务中使用size()或Hibernate.initialize()来初始化延迟加载的数据,例如:

publication.getFounders().size();

或者

Hibernate.initialize(publication.getFounders());

我最终采纳了你的建议。谢谢! - lorraine batol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接