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

时间:2015-11-18 06:20:01

标签: java hibernate jpa jpql

考虑以下模型

@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
 }

Address类使用@Embeddable注释进行注释,Employee类具有addresses的嵌入元素集合。元素集fetch设置为FetchType.LAZY。现在,我想创建一个@NamedQuery来检索所有急切初始化的地址的员工。知道基于JPA 2.1的JOIN FETCH will only work with entity collections使用@OneToMany@ManyToMany注释,我将如何创建一个有效的JPQL查询,以便我能够急切地检索嵌入式元素集合?

2 个答案:

答案 0 :(得分:6)

在JPA 2.1规范(JSR 338)中,我找不到任何关于fetch join仅适用于实体关系(但不能嵌入)的提示。 JSR 338,第4.4.5.3节甚至声明:

  

FETCH JOIN可以提取关联或元素集合作为执行查询的副作用。

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

地址嵌入:

@Embeddable public class Address { private String city; }

员工实体:

@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查询:

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

生成的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

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

答案 1 :(得分:2)

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

import.sql

它有两个选择,而不是一个,但不会产生这么多歧义。