13

Мне нужно преобразовать запрос критерии Hibernate как следующийИспользование Проекции в JPA 2

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(); 

Однако в 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)); 

однако не имеют ни малейшего представления о том, как осуществить проекцию здесь ни псевдоним

ответ

24

Это старый вопрос, но давайте приведем пример:

С 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); 

С другой стороны, если вы хотите запросить фактических значений «количество», вы можете сделать:

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

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

List<Integer> amounts = em.createQuery(cq).getResultList(); 
+0

+1 Наконец надлежащий пример суммы! – icl7126