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 Address
class is annotated with @Embeddable
annotation, and the Employee
class has an embedded element collection of addresses
. The element collection's fetch
is set to FetchType.LAZY
. Now, I would like to create a @NamedQuery
that would retrieve all employees with addresses eagerly initialized. Knowing that JOIN FETCH
will only work with entity collectionsannotated with @OneToMany
or @ManyToMany
based on JPA 2.1, how would I create a valid JPQL
query 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 JOIN
enables 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.
它进行了两次选择,而不是一次,但不会产生太多歧义。