Criteria api multiple projection - java

I have a problem with hibernate criteria api. I am trying to get two sum projections. However I always get only one column result with the second requested sum (for instant i.totalCostPrice), if I change the order of the sums in code, I will get the second one (i.totalPrice), but never both of them as I require. Does anybody know the solution please?
DetachedCriteria totalSumsCriteria = DetachedCriteria.forClass(Invoice.class, "i");
ProjectionList pList = Projections.projectionList();
pList.add(Projections.alias(Projections.sum("i.totalPrice"), "totalListPriceSum"));
pList.add(Projections.alias(Projections.sum("i.totalCostPrice"), "totalCostPriceSum"));
totalSumsCriteria.setProjection(pList);
totalSumsCriteria.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
the result is [589704.0], I expect [6127123.0, 589704.0], if I swap adding sum projectiosn, I get [6127123.0]
in SQL it would be something like SELECT SUM(total_price), SUM(total_cost_price) FROM invoice

If anyone is interested, the problem is with the DetachedCriteria. It works well with Crieteria, but not with DetachedCriteria.

Related

JPA CriteriaBuilder value like column

I'm trying to create a query using CriteriaBuilder where I need to have a predicate where the value of the predicate is like the value in the database.
Basically, I need to be able to do the following:
WHERE myTestValue LIKE columnValue
In native queries, it is an option to do that, but using the CriteriaBuilder or NamedQueries, it does not seem to work.
String myValue = "foo#bar.com";
cb.where(cb.like(myValue, root.get(Entity_.email));
Is there an option in JPA to do it like this? Or should I fall back to native queries?
EDIT
I need to be able to check if a given value matches a wildcard entry in database. So the database has a record %#bar.com%, and I need to check if my given value foo#bar.com matches to that record.
I think your params should be other way round:
cb.where(cb.like(root.get(Entity_.email),myValue);
Aditionally you may need to use add this to the second param:
cb.where(cb.like(root.get(Entity_.email),"%"+myValue+"%");
Chris found the answer. First I need to "generate" a parameter.
ParameterExpression<String> senderEmailParameter = cb.parameter(String.class, "senderEmailParameter");
Path<String> senderEmailPath = root.get(Entity_.senderEmail);
Predicate predEmail = cb.like(senderEmailParameter, senderEmailPath);
And then I need to fill the parameter in the query.
q.where(predEmail);
return em.createQuery(q).setParameter("senderEmailParameter", senderEmail).getSingleResult();
This works! Thanks Chris!

Why is this Java query failing? returning 0 when there are results

Hi can anyone tell me why this java query is failing?
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationID = :correlationId AND m.verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
long result = (long) q.getFirstResult();
The namedQuery:
#NamedQuery( name="MdmAuditDAO.GetData", query="SELECT m FROM MdmAuditDAO m WHERE m.correlationId = :correlationId AND m.verb = :verb")
public class MdmAuditDAO implements Serializable {
I have getters and setter in my MdmAuditDAO class, and I have checked the naming of the variables, and they are identical as in the NamedQuery, so the problem does not lie there.
My problem is that I have three entries in my database, I should at least get one answer back but I get 0 in my result.
MdmAuditDAO is defined in my persistence.xml and in my ehcache.xml. So why is it that the result I get returned is 0? I have also tried to get an object returned or a list of objects, and it is the same result, nothing gets returned, but when I run my query in my mssql database I get results see picture below. It has nothing to do with the m.* I aslo get results when I use that in my SELECT statement.
EDIT 1: This is what I get from my hibernate log, and I do not know how to read this?
Hibernate:
select
mdmauditda0_.id as id1_7_,
mdmauditda0_.correlationID as correlat2_7_,
mdmauditda0_.messageID as messageI3_7_,
mdmauditda0_.meter_no as meter_no4_7_,
mdmauditda0_.noun as noun5_7_,
mdmauditda0_.payload as payload6_7_,
mdmauditda0_.source as source7_7_,
mdmauditda0_.subtype as subtype8_7_,
mdmauditda0_.time as time9_7_,
mdmauditda0_.verb as verb10_7_
from
MdmAudit mdmauditda0_
where
mdmauditda0_.correlationID=?
Anything I have to set, to get more information? I am using the following jars
And my java version is 1.7.0_79.
I found the solution http://www.objectdb.com/api/java/jpa/Query/getFirstResult returns the position of the first element, but I was a bit confused by the phrase
Returns 0 if setFirstResult was not applied to the query object.
Could not get my head around it to make any sense of it.
My solution now is that I just return a list of objects
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationId = :correlationId AND verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
List<MdmAuditDAO> mdmAuditList = q.getResultList();
And then it works fine and I get results. So instead of the the result == 0 check I am doing later in my code I just do a NULL and isEmpty() check instead().
Side note: I have not tried to delete entries and then see what the result would be then in the q.getFirstResult() call but that would be a possibility and see what i get returned and then check on that value, properbly null?

Hibernate Criteria - Max value from a given list

I'm using Hibernate Criteria, I want to select the maximun value for each group of values, this maximun value must be contained in a given list.
Example:
select t.field1, max(t.field2) as total
from table t
where t.field2 in :givenList
group by t.field1
order by total desc;
I've tried doing this:
Criteria criteria = session.createCriteria(Table.class);
DetachedCriteria maxNo = DetachedCriteria.forClass(Table.class);
ProjectionList projection = Projections.projectionList();
projection.add(Projections.groupProperty("id.field1"));
projection.add(Projections.max("id.field2"));
maxNo.setProjection(projection);
criteria.add(Subqueries.propertiesIn(new String[] {"id.field1", "id.field2"}, maxNo));
This code works perfectly but it returns only the max value for each group.
If I try to add other constrains like:
criteria.add(Property.forName("id.field2").in(givenList));
The request doesn't work properly. Basic case, the maximun for the group is 2, and the given list is (0,1), in this case we receive nothing for this group.
I hope you could help me. Thanks in advance!
I've found the solution.
maxNo.add(Restrictions.in("id.field2", givenList));
Actually, I make a mistake placing the Restrictionsin the Criteria. We should place the Restrictions in the DetachedCriteria.
Thank you anyway

hibernate criteria api how to get Path from fetched records?

I have a query written in criteria api that goes like this:
CriteriaQuery<Application> query = builder.get().createQuery(Application.class).distinct(true);
Root<Application> root = query.from(Application.class);
root.fetch(Application_.answerSets, JoinType.LEFT);
I need to get Path for answerSet.createDate field, but have no idea how to achieve it. I need it to make a query for applications where answer sets are older than X days.
Try query.add(Restrictions.eq("answerSet.createDate", YOURVALUE)). However I am not if createQuery is the same as createCriteria.

how do I add another search parameter in hibernate mapping?

I am new to hibernate and still learning the basics. I'd appreciate if someone can point me in the right direction.
I have a class:
Destination
id
name
longitude
latitude
I can read destinations based on id with something like this:
List result = session.createQuery("from Destination as d where d.id=2").list();
However, I want to read destinations from database using name. I can perhaps write something like this as a query:
String name; // name set somewhere else, say a function argument
List result = session.createQuery("from Destination as d where d.name LIKE %"+name).list();
I believe this will yield all destinations with names similar to (variable) name.
Is there something inbuilt in hibernate for such use cases or is there a better way to handle this ?
EDIT:
One thing that follows from my thought process is: name column on destination db table will have an index setup. Can I map this index in some way to the Destination class using hibernate ?
You could build your query by concatenating strings. A more elegant solution would be to use the Hibernate Criteria API.
You query would then look something like:
List result = session.createCriteria(Destination.class)
.add(Restrictions.like("name", "%" + name)
.list();

Categories

Resources