【问题标题】:JPA Criteria API - null check on GROUP BYJPA Criteria API - 对 GROUP BY 进行空检查
【发布时间】:2020-09-15 11:03:56
【问题描述】:

我需要返回结果数组,其中分组列上的数据可能包含空值,并且当前已跳过这些结果,而我也希望将它们分组。

我的实体:

public class UserEntity {
// ...
    @Basic
    @Column(name = "username")
    private String username;
}

public class ZgloszenieEntity {
// ... 

    @ManyToOne
    @JoinColumn(name = "assigned_user_id" )
    @OrderBy("username")
    private UserEntity assignedUser;

    @ManyToOne(targetEntity = InternalStatusEntity.class)
    @JoinColumn(name = "internal_status")
    @NotAudited
    private InternalStatusEntity internalStatus;
}

受影响的代码:

  CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<EfficiencyStatusReportDTO> cq = cb.createQuery(EfficiencyStatusReportDTO.class);
        Root<ZgloszenieEntity> root = cq.from(ZgloszenieEntity.class);
        Join<UserEntity, ZgloszenieEntity> join = root.join("assignedUser");

        cq.multiselect(join.get("username")
                , root.get("internalStatus").get("description")
                , getNumberOfDocOfType(cb, root, "X-1")
                , getNumberOfDOcOfType(cb, root, "X-2")
                , getNumberOfDocOfType(cb, root, "X-3")
                , getNumberOfDocOfType(cb, root, "X-4")
                , cb.count(root)
        );
        cq.groupBy(join.get("username"), root.get("internalStatus").get("description"));

它适用于具有 internalStatus != null 的实体,但可以在没有连接 InternalStatus 的情况下拥有它,然后我希望将它按 null 分组。

当前示例结果:

// ... 
        {
            "username": "admin@gmail.com",
            "internalStatus": "Do stuff",
            "numberOfDoc1": 0,
            "numberOfDoc2": 2,
            "numberOfDoc3": 1,
            "numberOfDoc4": 0,
            "sumOfDoc": 3
        },

我希望它也有这样的结果:

        {
            "username": "admin@gmail.com",
            "internalStatus": null,
            "numberOfDoc1": 4,
            "numberOfDoc2": 1,
            "numberOfDoc3": 5,
            "numberOfDoc4": 0,
            "sumOfDoc": 10
        },

JPA 生成的查询:

select userentity1_.username                                          as col_0_0_,
       internalst2_.description                                       as col_1_0_,
       count(case when zgloszenie0_.form_type='X-1' then 1 else null end) as col_2_0_,
       count(case when zgloszenie0_.form_type='X-2' then 1 else null end) as col_3_0_,
       count(case when zgloszenie0_.form_type='X-3' then 1 else null end) as col_4_0_,
       count(case when zgloszenie0_.form_type='X-4' then 1 else null end) as col_5_0_,
       count(zgloszenie0_.uid)                                        as col_6_0_
from zgloszenie zgloszenie0_
         inner join user userentity1_ on zgloszenie0_.assigned_user_id = userentity1_.id
         cross join internal_status internalst2_
where zgloszenie0_.internal_status = internalst2_.id
  and 1 = 1
group by userentity1_.username, internalst2_.description
order by userentity1_.username desc

有没有办法将自动创建的交叉连接更改为考虑空值?

【问题讨论】:

    标签: java sql jpa join criteria-api


    【解决方案1】:

    试试这个

     CriteriaBuilder cb = em.getCriteriaBuilder();
     CriteriaQuery<EfficiencyStatusReportDTO> cq = 
         cb.createQuery(EfficiencyStatusReportDTO.class);
     Root<ZgloszenieEntity> root = cq.from(ZgloszenieEntity.class);
     Join<ZgloszenieEntity, UserEntity> assignedUser = root.join("assignedUser", 
         JoinType.LEFT);
     Join<ZgloszenieEntity, InternalStatus> internalStatus = root.join("internalStatus", 
         JoinType.LEFT);
    
     cq.multiselect(assignedUser.get("username"), 
                    internalStatus.get("description"),
                    getNumberOfDocOfType(cb, root, "X-1"),
                    getNumberOfDOcOfType(cb, root, "X-2"),
                    getNumberOfDocOfType(cb, root, "X-3"),
                    getNumberOfDocOfType(cb, root, "X-4"),
                    cb.count(root)
     );
     cq.groupBy(assignedUser.get("username"), internalStatus.get("description"));
    

    【讨论】:

    • Join中的类型顺序不正确,是倒序的。其余的都是正确的方法。
    • @JLazar0 谢谢!我从问题中漫不经心地复制粘贴了它。已编辑
    • 谢谢!效果很好,欣赏。
    猜你喜欢
    • 2015-07-25
    • 2015-02-27
    • 2020-02-22
    • 2016-03-09
    • 2016-10-11
    • 2012-01-19
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多