使用JPA Criteria API生成正确的和/或条件

时间:2016-11-29 18:17:24

标签: java sql jpa jpa-2.0 criteria-api

我正在尝试使用'或'和'和'条件中的多个括号生成查询,但不会生成内部括号。 外部谓词的括号正在生成,但不适用于内部谓词。 代码:

    CriteriaBuilder criteriaBuilder = this.getEntityManager().getCriteriaBuilder();
    CriteriaQuery<ConfigurationKey> query = criteriaBuilder.createQuery(ConfigurationKey.class);
    Root<ConfigurationKey> configurationKeyRoot = query.from(ConfigurationKey.class);
    Join<ConfigurationKey, Customer> configurationKeyCustomerJoin = configurationKeyRoot.join(ConfigurationKey_.customer);

    final List<Predicate> predicates = new ArrayList<>();
    predicates.add(criteriaBuilder.equal(configurationKeyCustomerJoin.get(Customer_.externalId), customerId));
    predicates.add(criteriaBuilder.equal(configurationKeyRoot.get(ConfigurationKey_.configType), configType));

    final List<Predicate> orPredicates = new ArrayList<>();
    keys.forEach((x, y) -> {
                orPredicates.add(
                        criteriaBuilder.and(
                                criteriaBuilder.equal(configurationKeyRoot.get(ConfigurationKey_.keyType), x),
                                criteriaBuilder.equal(configurationKeyRoot.get(ConfigurationKey_.keyValue), y)
                        )
                );
            }

    );

    predicates.add(criteriaBuilder.or(orPredicates.toArray(new Predicate[orPredicates.size()])));
    query.where(criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])));
    query.select(configurationKeyRoot);
    TypedQuery<ConfigurationKey> typedQuery = this.getEntityManager().createQuery(query);

生成的查询:

select
    configurat0_.id as id1_1_,
    configurat0_.createdAt as createdA2_1_,
    configurat0_.updatedAt as updatedA3_1_,
    configurat0_.configType as configTy4_1_,
    configurat0_.customerId as customer7_1_,
    configurat0_.keyType as keyType5_1_,
    configurat0_.keyValue as keyValue6_1_ 
from
    configuration_keys configurat0_ 
inner join
    customers customer1_ 
        on configurat0_.customerId=customer1_.id 
where
    customer1_.externalId=? 
    and configurat0_.configType=? 
    and (
        configurat0_.keyType=? 
        and configurat0_.keyValue=? 
        or configurat0_.keyType=? 
        and configurat0_.keyValue=?
    )

预期查询:

select
    configurat0_.id as id1_1_,
    configurat0_.createdAt as createdA2_1_,
    configurat0_.updatedAt as updatedA3_1_,
    configurat0_.configType as configTy4_1_,
    configurat0_.customerId as customer7_1_,
    configurat0_.keyType as keyType5_1_,
    configurat0_.keyValue as keyValue6_1_ 
from
    configuration_keys configurat0_ 
inner join
    customers customer1_ 
        on configurat0_.customerId=customer1_.id 
where
    customer1_.externalId=? 
    and configurat0_.configType=? 
    and (
        (configurat0_.keyType=? 
        and configurat0_.keyValue=?) 
        or 
        (configurat0_.keyType=? 
        and configurat0_.keyValue=?)
    )

请指出任何错误。

1 个答案:

答案 0 :(得分:0)

tomcat