在注释与@OneToMany的关系时是否可以定义LEFT Join?

时间:2015-02-13 13:55:03

标签: java hibernate jpa one-to-many criteria-api

我有以下情况

@Entity
public class Parent {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name", nullable = false)
    private String name;

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy = "parent", orphanRemoval = true)
    private Set<Child> children;
   }
@Entity
public class Child {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch=FetchType.LAZY, optional = false)
    private Parent parent;
}

使用JPA Criteria或JPQL构建查询时,默认情况下,在请求为子项提取联接时,我会获得内部联接。

使用:

SELECT p from Parent p JOIN p.children

OR

EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Parent> query = cb.createQuery(Parent.class);

Root<Parent> root = query.from(Parent.class);
root.fetch(Parent_.children);
query.distinct(true);

List<Parent> result = em.createQuery(query).getResultList();

如何避免此默认行为(内连接)? 我的目标是在指定OneToMany关系时默认获得LEFT JOIN ... 在构建查询时是否可以明确设置JoinType.LEFT?

非常感谢任何帮助。 提前谢谢

2 个答案:

答案 0 :(得分:1)

  

在构建查询时是否可以不显式设置JoinType.LEFT?

不,不是!隐式连接是INNER JOIN,如果您在JPQL查询中导航关联,则会假定它。

如果您还需要获取子关联,则必须使用LEFT JOIN和FETCH:

SELECT p 
from Parent p 
LEFT JOIN FETCH p.children

或使用Criteria API:

EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Parent> query = cb.createQuery(Parent.class);

Root<Parent> root = query.from(Parent.class);
root.fetch(Parent_.children, JoinType.LEFT);
query.distinct(true);

List<Parent> result = em.createQuery(query).getResultList();

答案 1 :(得分:-1)

您可以尝试Blaze-Persistence,因为它会以您期望的方式隐式加入,即只有在保留行数时才会进行内连接。

List<Parent> result = cbf.create(em, Parent.class).fetch("children").getResultList();

产生

SELECT p 
FROM Parent p 
LEFT JOIN FETCH p.children