13

necesito convertir una consulta de Hibernate criterios como la siguienteutilizando proyecciones en 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(); 

Sin embargo, en JPA (2) no tengo idea de cómo poner en práctica la proyección - en este caso - la suma. Es extraño que Hibernate y JPA (incluso Hibernate JPA 2) tengan estas tremendas diferencias especialmente en consultas de criterios.

que empezar por

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

sin embargo no tienen idea de cómo poner en práctica la proyección aquí ni el alias

Respuesta

24

Es una vieja pregunta, pero vamos a dar un ejemplo:

Con CriteriaBuilder, a diferencia Hibernate, siempre comienza con el tipo del resultado que desea consultar y luego crea la proyección.

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

Por otro lado, si usted quería para consultar los valores reales "cantidad", que podría hacer:

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 ejemplo Finalmente adecuado suma! – icl7126

Cuestiones relacionadas