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
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!
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?
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
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.
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();