El uso de Proyecciones en JPA 2

Que necesito para convertir una Hibernación de los criterios de consulta como la siguiente

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 implementar la proyección – en este caso – el de la suma. Es curioso que Hibernate y JPA (incluso Hibernate JPA 2) un tremendo diferencias especialmente en los criterios de las consultas.

Empiezo 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 implementar la proyección aquí ni el alias

OriginalEl autor Skyhan | 2012-03-21

1 Kommentar

  1. 29

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

    Con CriteriaBuilder, a diferencia de Hibernación, que siempre empieza con el tipo del resultado que desea consultar y luego construir 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 consultar por el real de la «cantidad» de los valores, se podría:

    CompoundSelection<Integer> projection = cb.construct(Integer.class, cb.sum(isr.get("amount")));
    
    cq.where(..).select(projection);
    
    List<Integer> amounts = em.createQuery(cq).getResultList();
    +1 Finalmente adecuado ejemplo de suma!

    OriginalEl autor user2037910

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea