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
JPA: How to fetch eagerly an embedded element collection
提问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.
A
FETCH 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.
它进行了两次选择,而不是一次,但不会产生太多歧义。

