有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

其他实体的可空属性上的java Spring可分页排序

我遇到了以下问题。。。我有三个实体:

@Entity
class Contract {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    private Employee employee;
}

@Entity
class Employee {

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

    @ManyToOne
    private Department department;
}

@Entity
class Department {

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

    private String name;
}

以及使用规范获取合同信息的方法:

Page<Contract> getContracts(Integer employeeId, Pageable pageable) {
    return contractRepository.findAll(createSpecification(employeeId), pageable);
}

Specification<Contract> createSpecification(Integer employeeId) {
    return Specification.where(equalEmployeeId(employeeId));
}

Specification<Contract> equalEmployeeId(Integer employeeId) {
        return (root, criteriaQuery, criteriaBuilder) -> {
            if (Objects.nonNull(employeeId)) {
                Join<Contract, Employee> joinParent = root.join("employee");
                return criteriaBuilder.equal(joinParent.get("id"), employeeId);
            } else {
                return criteriaBuilder.isTrue(criteriaBuilder.literal(true));
            }
        };
    }

现在,我的应用程序允许按Department名称对Contract实体进行排序,因此Pageable对象的sort参数设置为employee.department.name。当Employee对象的department参数设置为null时,问题就出现了。。。例如,如果所有Employee对象的department参数都设置为null,则返回空集合。如何更改此行为以返回所有Contract实体,而不管Employee's{}是否为空

我已经尝试过不同的方法:将fetchjoin添加到规范中,将spring.jpa.properties.hibernate.order_by.default_null_ordering设置为last,但没有任何帮助

提前感谢您的帮助

PS:请不要建议我放弃规范等——为了可读性,我提供的代码被简化了。实际上,有更多的属性,使用规范进行过滤是最方便的方法


共 (3) 个答案

  1. # 1 楼答案

    你知道什么有用吗?正在将Spring引导更新到2.5.0。。。现在它可以正常工作了。。。(谢谢@tremendous7给我灵感!) 然而,我想@jonathanjohx提供的答案可能适用于较旧的版本

  2. # 2 楼答案

    如果Department为空,则基于您想要返回所有Contract实体的内容

    Specification<Contract> equalEmployeeId(Integer employeeId) {
        return (root, criteriaQuery, criteriaBuilder) -> {
            Join<Contract, Employee> joinParent = root.join("employee");
            if (Objects.nonNull(employeeId)) {
                return criteriaBuilder.equal(joinParent.get("id"), employeeId);
            } else {
                return criteriaBuilder.isTrue(joinParent.get("department").isNull());
            }
        };
    }
    
  3. # 3 楼答案

    您需要实现左连接以获取空内容:

    Join<Contract, Employee> joinParent = root.join("employee",JoinType.LEFT);
    

    部门也是如此