java JPA:如何急切地获取嵌入的元素集合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33773079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 22:07:12  来源:igfitidea点击:

JPA: How to fetch eagerly an embedded element collection

javahibernatejpajpql

提问by Warren M. Nocos

Consider the following model

考虑以下模型

@Entity
// JPA and JAXB annotations here
public class Employee implements Serializable {
     // other fields, annotations, stuffs
     ...
     @ElementCollection(fetch = FetchType.LAZY,
        targetClass = Address.class)
     @CollectionTable(name = "employee_address",
        schema = "hris",
        joinColumns = @JoinColumn(name = "employee_id",
                nullable = false,
                referencedColumnName = "employee_id",
                foreignKey = @ForeignKey(ConstraintMode.CONSTRAINT)))
     protected Set<Address> addresses;
     // setters, getters
     ...
 }

 @Embeddable
 // JAXB annotations here
 public class Address implements Serializable {
      // fields, setters, getters
 }

The Addressclass is annotated with @Embeddableannotation, and the Employeeclass has an embedded element collection of addresses. The element collection's fetchis set to FetchType.LAZY. Now, I would like to create a @NamedQuerythat would retrieve all employees with addresses eagerly initialized. Knowing that JOIN FETCHwill only work with entity collectionsannotated with @OneToManyor @ManyToManybased on JPA 2.1, how would I create a valid JPQLquery that would allow me to eagerly retrieve embedded element collections?

Address类都被注解@Embeddable注解,和Employee类具有一个嵌入元件集合addresses。元素集合的fetch设置为FetchType.LAZY。现在,我想创建一个@NamedQuery可以检索地址急切初始化的所有员工。知道JOIN FETCH这只适用于使用 JPA 2.1注释@OneToMany@ManyToMany基于 JPA 2.1 的实体集合,我将如何创建一个有效的JPQL查询来允许我急切地检索嵌入的元素集合?

回答by 8hZWKA

In the JPA 2.1 specification (JSR 338) I cannot find any hint that fetch joins only work on entity relationships (but not embeddables). JSR 338, section 4.4.5.3 even states:

在 JPA 2.1 规范 (JSR 338) 中,我找不到任何提示,即 fetch joins 仅适用于实体关系(但不适用于 embeddables)。JSR 338,第 4.4.5.3 节甚至指出:

A FETCH JOINenables the fetching of an association or element collectionas a side effect of the execution of a query.

AFETCH JOIN允许获取关联或元素集合作为查询执行的副作用。

As another hint the following minimal example (essentially resembling yours) executed with Hibernate 4.3.11 as JPA provider results in a single query:

作为另一个提示,使用 Hibernate 4.3.11 作为 JPA 提供程序执行的以下最小示例(基本上类似于您的示例)会导致单个查询:

Address embeddable:

可嵌入地址:

@Embeddable public class Address { private String city; }

Employee entity:

员工实体:

@Entity public class Employee {

    @Id private Long id;

    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(name = "address", 
           joinColumns = @JoinColumn(name="employee_id"))
    private Set<Address> addresses;

}

JPQL Query:

JPQL 查询:

em.createQuery("select e from Employee e join fetch e.addresses").getResultList();

Resulting SQL query:

结果 SQL 查询:

select
    employee0_.id as id1_1_,
    addresses1_.employee_id as employee1_1_0__,
    addresses1_.city as city2_5_0__ 
from
    Employee employee0_ 
inner join
    address addresses1_ on employee0_.id=addresses1_.employee_id

So the above JPQL query seems to solve your problem.

所以上面的 JPQL 查询似乎解决了你的问题。

回答by Oleg Gritsak

By the way, more effective way might be notto use join, but subselect

顺便说一句,更有效的方法可能不是使用 join,而是 subselect

@Fetch(FetchMode.SUBSELECT)
@BatchSize(size=500)

it makes two selects, instead of one, but doesn't produce so much ambiguity.

它进行了两次选择,而不是一次,但不会产生太多歧义。