2

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

@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));
            }
        };
    }

现在,我的应用程序提供了Contract按名称对实体进行排序的可能性Department,因此出现了参数设置为的Pageable对象。当对象的参数设置为空时,问题就出现了……例如,如果所有对象的参数都设置为空,则返回空集合。我可以做些什么来改变这种行为以返回所有实体,无论是否为空?sortemployee.department.nameEmployeedepartmentEmployeedepartmentContractEmployee's department

我已经尝试过不同的事情:将 fetch join 添加到规范中,设置spring.jpa.properties.hibernate.order_by.default_null_orderinglast,但没有任何帮助。

预先感谢您的任何帮助!

PS:请不要建议我摆脱规范等 - 为了便于阅读,我提供的代码已被简化。实际上,还有更多的属性,使用规范进行过滤是最方便的方法。

4

3 回答 3

4

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

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());
        }
    };
}
于 2021-05-25T03:28:59.720 回答
1

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

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

同样对于部门

于 2021-05-23T03:08:06.257 回答
1

你知道有什么帮助吗?将 Spring Boot 更新到 2.5.0 ......现在它按预期工作......(感谢@tremendous7 的启发!)但是,我想@jonathan-johx 提供的答案可能适用于旧版本......

于 2021-05-26T12:22:18.437 回答