条件API有条件地评估'NULL'

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

我有以下Criteria API查询,用于根据多个Subject属性评估给定值。

...
    Expression literal = builder.literal((String) "%" + filterValue + "%");

    // When the globalFilter is deleted it returns ""
    if (!"".equals(filterValue)) {
        // JPQL equivilant: SELECT e FROM Subject e JOIN e.company c JOIN e.contact ct WHERE c.name LIKE :literal OR ct.firstName LIKE :literal ... etc
        List<Predicate> globalPredicate = new ArrayList<>();

        globalPredicate.add(builder.like(subject.get(Subject_.email), literal));
        globalPredicate.add(builder.like(subject.join(Subject_.contact).get(Contact_.firstName), literal));
        globalPredicate.add(builder.like(subject.join(Subject_.contact).get(Contact_.lastName), literal));
        globalPredicate.add(builder.like(subject.join(Subject_.metier).get(Metier_.name), literal));
        globalPredicate.add(builder.like(subject.join(Subject_.company).get(Company_.name), literal));

        predicates.add(builder.or(globalPredicate.toArray(new Predicate[globalPredicate.size()])));
    }
...

这将创建以下查询:

SELECT t1.UID AS a1, t1.EMAIL AS a2, t1.PASSWORD AS a3, t1.VERSION AS a4, t1.COMPANY_ID AS a5, t1.METIER_ID AS a6, t1.ACCOUNT_ID AS a7, t1.CONTACT_ID AS a8 FROM METIER t3, COMPANY t2, SUBJECT t1, CONTACT t0 WHERE (((((t1.EMAIL LIKE ? OR t0.FIRSTNAME LIKE ?) OR t0.LASTNAME LIKE ?) OR t3.NAME LIKE ?) OR (t2.NAME LIKE ? IS NOT NULL)) AND (((t0.ID = t1.CONTACT_ID) AND (t3.ID = t1.METIER_ID)) AND (t2.ID = t1.COMPANY_ID))) LIMIT ?, ?

我遇到的问题是Subject_.company可能是null。该查询有效地忽略了Subject_.company设置为null的所有条目。

我需要以某种方式修改此查询,以便不会自动丢弃null值。

jpa null criteria-api
1个回答
2
投票

您需要使用带有JoinType参数的join方法,并指定JoinType.LEFT,以便它使用左外部联接而不是默认的外部联接。

globalPredicate.add(builder.like(subject.join(Subject_.company, JoinType.LEFT).get(Company_.name), literal));

左外部联接将防止Subject-> Company关系过滤掉空公司的结果。

© www.soinside.com 2019 - 2024. All rights reserved.