Using Projections in JPA 2

断了今生、忘了曾经 提交于 2019-11-30 12:43:32

问题


I need to convert a Hibernate criteria query like the following

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

However in JPA (2) I have no idea how to implement the projection - in this case - the sum. It's odd that Hibernate and JPA (even Hibernate JPA 2) have this tremendous differences especially in criteria queries.

I start by

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

however have no idea how to implement the projection here neither the alias


回答1:


It's an old question, but let's give an example:

With CriteriaBuilder, unlike Hibernate, you always start off with the type of the result you want to query and then construct the projection.

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

On the other hand if you wanted to query for the actual "amount" values, you could do:

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

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

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


来源:https://stackoverflow.com/questions/9802717/using-projections-in-jpa-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!