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

rod*_*tes 5 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;
}
Run Code Online (Sandbox Code Playgroud)

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

要么使用:

SELECT p from Parent p JOIN p.children
Run Code Online (Sandbox Code Playgroud)

或者

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();
Run Code Online (Sandbox Code Playgroud)

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

任何帮助都非常感谢。先感谢您

Vla*_*cea 4

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

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

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

SELECT p 
from Parent p 
LEFT JOIN FETCH p.children
Run Code Online (Sandbox Code Playgroud)

或使用 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();
Run Code Online (Sandbox Code Playgroud)

  • 不,这是不可能的。当您默认获取内连接或显式指定左外连接时。 (3认同)