【问题标题】:criteriaBuilder.construct() select property of nullable child entity in DTO ProjectioncriteriaBuilder.construct() 在 DTO 投影中选择可为空的子实体的属性
【发布时间】:2021-09-10 15:47:59
【问题描述】:

在 XyzEntity 用户字段中包含空值和非空值

(这里root.get(XyzEntity_.user)可以为null

代码 1:

criteriaQuery.select(criteriaBuilder.construct(XyzStatusDTO.class, root.get(XyzEntity_.ID), 
                root.get(XyzEntity_.user).get(UserEntity_.ID),
                root.get(XyzEntity_.user).get(UserEntity_.EMAIL)
           ));

代码 2:

 criteriaQuery.select(criteriaBuilder.construct(XyzStatusDTO.class, root.get(XyzEntity_.ID), 
                root.get(XyzEntity_.user).get(UserEntity_.ID) 
           ));

代码 3:

 criteriaQuery.select(criteriaBuilder.construct(XyzStatusDTO.class, root.get(XyzEntity_.ID) 
           ));

代码 1 返回 12 条记录(仅当用户不为空时),而代码 2 和代码 3 返回 300 条结果(包括空用户)。

任何建议我可以在哪里放置条件语句,例如用户是否为空或非空)。因此,如果用户为空,则值 id user Id 和 email 将为空,而不是跳过结果。

【问题讨论】:

    标签: hibernate jpa spring-data-jpa hibernate-criteria criteria-api


    【解决方案1】:

    你需要的是左连接

          Join<XyzEntity, UserEntity> userEntityJoin = root.join("user", JoinType.LEFT);
          criteriaQuery.select(criteriaBuilder.construct(XyzStatusDTO.class, root.get(XyzEntity_.ID), 
                userEntityJoin.get(UserEntity_.ID),
                userEntityJoin.get(UserEntity_.EMAIL)
           ));
    

    【讨论】:

    • 谢谢!我想了想,但不知何故忘了补充。你能解释一下如果我只获取子实体的 pk 是如何工作的(代码 2 工作,而代码 1 失败)
    • @Tusar 代码 2 有效,因为没有隐式内部连接。当您选择 UserEntity 的字段时,会启动隐式默认内部联接。这就是为什么 1 “失败”。原因是 jpa 隐式默认连接是内连接。使用内部连接,您只保留两个表中具有匹配值的记录。解决方案是使用左连接,因为即使没有右值baeldung.com/…,您也总是希望选择左连接
    猜你喜欢
    • 2010-09-13
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    相关资源
    最近更新 更多