java - JPA - 使用 Root、Join 在字段上加入获取

标签 java hibernate jpa join

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

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)

最佳答案

JPA 规范说:

Multiple levels of fetch joins are not required to be supported by an implementation of this specification. Applications that use multi-level fetch joins will not be portable.

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

publication.getFounders().size();

Hibernate.initialize(publication.getFounders());

关于java - JPA - 使用 Root、Join 在字段上加入获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25909552/

相关文章:

java - 我的用户界面在同一窗口中显示两次

java - persistence.xml 中的 jar 文件名问题

java - Selenium 更新后 ExpectedConditions 将不起作用

java - 我正在尝试创建一个简单的 hibernate 应用程序。它给出以下错误。如何解决该错误

java - 单表的多个 POJO/实体

java - 为什么我的 EmbeddedId 在 hibernate 中不起作用?

java - 子类可以与父类(super class)具有相同的列名吗?

java - 如何从字符串中解析 double 值并比较它们?

java - 类型不匹配 : cannot convert from List to ILogin

java - JPA 和 PostgreSQL : How do I call a stored procedure with void return type?