criteriaBuilder notEqual 函数不会为 ManyToOne 类返回空值

问题描述 投票:0回答:2

我有如下两节课

public class User {

    @Column(name = "EMP_NAME")
    private String name;

    @Column(name = "EMP_PASSWORD")
    private String password;
    
    @ManyToOne
    @JoinColumn(name = "ROLE_ID")
    private Role role;
    ....
}

public class Role {

    @column("ROLE_NAME")
    private String name;

    @column("IS_MASTER")
    String isMaster; // 'Y' or 'N'
    ...
}

我需要获取所有非主用户或没有角色的用户。为此,我尝试了类似的方法,但没有成功。

Predicate nonMaster =  cb.notEqual(root.get("role").get("isMaster"), "Y");
cb.and(nonMaster)

但这不会返回没有角色值(ROLE_ID == NULL)的用户。我也尝试过这个,但还是不行。

Predicate nonMaster =  cb.notEqual(root.get("role").get("isMaster"), "Y");
Predicate nullRole =  cb.isNull(root.get("role"));
cb.or(nullRole,nonMaster);

如何进行类似 role is null 或 role.isMaster 等于“N”的查询

java jpa criteria predicate hibernate-criteria
2个回答
0
投票

为了解决这个问题,我将查询设置为左连接。这样我就可以取空值。

Root<User> root = q.from(User.class);
root.join(User_.role,JoinType.LEFT);

0
投票

您描述的行为并非特定于 Hibernate 或 Spring Data,而是特定于某些数据库管理系统 (DBMS) 的默认行为。当使用诸如“WHERE ... attribute != 'value' ...”之类的谓词将查询发送到数据库时,某些 DBMS 在执行此查询时会自动排除 NULL 值。这可以解释您所观察到的行为。

要解决此问题,您可以在查询中明确指定要包含 NULL 值,例如,如有必要,使用“IS NOT NULL”子句。这将取决于您的具体用例和应用程序的要求。

这是一个解决方法:

public Specification<T> propertyNotEquals(final String property, final Object value) {
    //Assert.notNull(property, "property cannot be null");
    //Assert.notNull(value, "value cannot be null");
    return (root, query, builder) -> builder.or(
            builder.isNull(root.get(property)),
            builder.notEqual(root.get(property), value));
}
© www.soinside.com 2019 - 2024. All rights reserved.