在JPA 2中使用预测

Sky*_*han 18 hibernate projection criteria-api hibernate-criteria jpa-2.0

我需要转换Hibernate条件查询,如下所示

curList = session.createCriteria(Islem.class)
                    .createAlias("workingDay", "d")
                    .setProjection(Projections.sum("amount"))
                    .add(Restrictions.eq("currency", CURRENCY))
                    .add(Restrictions.eq("product", product))
                    .add(Restrictions.ne("status", INACTIVE))
                    .add(Restrictions.eq("d.status", ACTIVE))
                    .getResultList();
Run Code Online (Sandbox Code Playgroud)

然而在JPA(2)中,我不知道如何实现投影 - 在这种情况下 - 总和.奇怪的是,Hibernate和JPA(甚至是Hibernate JPA 2)在标准查询中存在巨大差异.

我开始

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Islem> cq = cb.createQuery(Islem.class);
Root<Islem> isr = cq.from(Islem.class);
cq.select(isr).where(cb.equal(isr.get("currency"), CURRENCY), 
                     cb.notEqual(isr.get("status"), INACTIVE),
                     cb.equal(isr.get("product"), product));
Run Code Online (Sandbox Code Playgroud)

但是不知道如何在这里实现投影既不是别名

小智 32

这是一个老问题,但让我们举个例子:

随着CriteriaBuilder不像Hibernate,就始终与开始结果的类型要查询,然后构造的投影.

CriteriaBuilder cb = em.getCriteriaBuilder();
//We want Integer result
CriteriaQuery<Integer> cq = cb.createQuery(Integer.class);

//The root does not need to match the type of the result of the query!
Root<Islem> isr = cq.from(Islem.class);

//Create a join to access the variable status of working day
Join<Islem,WorkingDay> join = isr.join("workingDay",JoinType.INNER);

//Create the sum expression
Expression<Integer> sum = cb.sum(isr.get("amount"));

cq.where(
         cb.equal(isr.get("currency"), CURRENCY),
         cb.notEqual(isr.get("status"), INACTIVE),
         cb.equal(isr.get("product"), product),
         cb.equal(join.get("status"), ACTIVE)
).select(sum);
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您想查询实际的"金额"值,您可以:

CompoundSelection<Integer> projection = cb.construct(Integer.class, cb.sum(isr.get("amount")));

cq.where(..).select(projection);

List<Integer> amounts = em.createQuery(cq).getResultList();
Run Code Online (Sandbox Code Playgroud)