【问题标题】:How to avoid INNER JOIN when returning a related entity using a custom constructor in JPQL在 JPQL 中使用自定义构造函数返回相关实体时如何避免 INNER JOIN
【发布时间】:2025-12-17 15:20:02
【问题描述】:

我有这样的事情:

@Entity
public class User implements Serializable {
  ...
  public User(String login, Division division) {
      this.login = login;
      this.division = division;
  }

  @ManyToOne
  public Division getDivision() {
      return division;
  }
  ...

JQPL:

我在这里使用自定义构造函数,因为我不希望查询返回用户的密码(和其他属性)。

SELECT new com.xyz.app.beans.User(u.login, u.division)
FROM User u
WHERE u.login = :login

生成的 SQL:

select
    user0_.login as col_0_0_,
    user0_.division_id as col_1_0_
from
    dbo.User user0_ 
inner join
    dbo.Division division1_ 
        on user0_.division_id=division1_.id 
where
    user0_.login=?

显然,如果 Division 为空,我的查询将返回一个空列表或抛出 NoResultException。 我希望查询返回用户,无论他是否有部门。

有办法避免这种情况吗? 如何告诉 Hibernate 执行 LEFT JOIN 而不是 INNER JOIN?

【问题讨论】:

    标签: java hibernate jpa jpql


    【解决方案1】:

    由于您在select 子句中使用u.division,它会隐式转换为内连接。要包括没有分部的用户,请使用此

    SELECT new com.xyz.app.beans.User(u.login, d)
    FROM User u left join u.division d
    WHERE u.login = :login
    

    【讨论】:

    • 添加 fetch = FetchType.LAZY 并没有解决问题,生成的SQL是一样的。在 SQL 中添加 left join u.division 和额外的连接,但它一直使用内连接。 PS.:我意识到最好不要级联,所以我编辑了这个问题。
    最近更新 更多