Simple HQL Query and Criteria in Hibernate - java

I have to write that HQL query:
FROM Sending adp WHERE adp.id = (SELECT MAX (adpw.id) FROM Sending adpw WHERE adpw.place = adp.place)
I have to use Criteria API and I can't manage it. Query returns last sendings from all places in database and it works very well but now I have to transform it to Criteria. The only thing I managed is to show just one place with following code:
Criteria criteria = getSession().createCriteria(
Sending.class);
criteria.setFetchMode("place", FetchMode.JOIN);
DetachedCriteria maxId = DetachedCriteria.forClass(Sending.class).setProjection(Projections.max("id"));
criteria.add(Property.forName("id").eq(maxId));
Could you help me? Thanks in advance!!

Sorry for answering my own question, but I found the solution.
I forgot that Subqueries can be correlated with themselves. I realized my query with following code:
Criteria criteria = getSession().createCriteria(Sending.class);
DetachedCriteria dc = DetachedCriteria.forClass(Sending.class, "adpw");
dc.add(Restrictions.eqProperty("adpw.place", "adp.place"));
dc.setProjection(Projections.max("id"));
criteria.add(Property.forName("id").eq(dc));
criteria.setMaxResults(count).setFirstResult(start);
return criteria.list();
Everything works now very well.

Related

Is this query possible using Criteria or DetachedCriteria Hibernate

The question is simple can this query be done in Hibernate using Criteria or DetachedCriteria? i guess not but i wanted to do this question maybe exist a workaround.
SELECT
COLUMNS
FROM table
WHERE id not in (
SELECT * FROM (
SELECT id
FROM table
WHERE
SOMECONDITIONS
ORDER BY timestamp desc limit 0, 15
)
as t);
I will mark the answer by #Dean Clark as correct but another question arises is the following
where can i find the findByCriteria from SessionFactory we are not using Spring
To exactly match you query, you really need to do it with 2 steps, but I'd avoid this if possible:
final Criteria innerCriteria = getSession().createCriteria(YourEntity.class);
// SOME CONDITIONS
innerCriteria.add(Restrictions.eq("someColumn", "someValue"));
innerCriteria.addOrder(Order.desc("timestamp"));
innerCriteria.setMaxResults(15);
innerCriteria.setProjection(Projections.id());
List<YourIdClass> ids = innerCriteria.list();
final Criteria criteria = getSession().createCriteria(YourEntity.class);
criteria.add(Restrictions.not(Restrictions.in("id", ids)));
List<YourEntity> results = criteria.list();
Would the objects you're trying to identify have the same "SOMECONDITIONS"? If so, this would functionally accomplish what you're looking for:
final DetachedCriteria criteria = DetachedCriteria.forClass(YourEntity.class);
// SOME CONDITIONS
criteria.add(Restrictions.eq("someColumn", "someValue"));
criteria.addOrder(Order.desc("timestamp"));
getHibernateTemplate().findByCriteria(criteria, 16, 9999999);

How to use CONCAT_WS() in Hibernate HQL

To combine multiple columns as one,
I found one answer
SELECT id,CONCAT_WS(',', field_1, field_2, field_3, field_4) list
FROM `table`;
This query working fine in SQL but it gives me error in HQL:
Error is .
(java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode )
please help me to find out what wrong i did, help me to know how to use CONCAT_WS() IN HQL
below how i written my HQL query
SELECT C1._URI,C1.HEALTH_FACILITY,C1.DISTRICT,CONCAT_WS(',', C1.BLOCKS_OF_BHUBRI, C1.BLOCKS_OF_GOLAGHAT, C1.BLOCKS_OF_HAILAKANDI) as Block_name
FROM GapAnalysisWashInHealthFacilitiesCore C1
any help will appreciate
CONCAT_WS is a function specific to mySql. HQL is a generic language and not aware of native SQL functions and syntax. If you really need the function, then you should use Hibernate's API for native SQL.
Session session = ...;
Query query = session.createSQLQuery("
SELECT id,CONCAT_WS(',', field_1, field_2, field_3, field_4) Block_name FROM `table`");
List result = query.list();
Then you may like to have a look at Result Transformers to get result as list of GapAnalysisWashInHealthFacilitiesCore objects.

Issue in getting db data using Hibernate query

Please look below db table relationship
comapny to product->many to many
product to item->many to many
Now, I need to get All items used in a company by using hibernate. Below is my efforts.
Criteria c = sessionFactory.getCurrentSession().createCriteria(Company.class);
c.add(Restrictions.eq("companyId", companyId));
Criteria c2 = sessionFactory.getCurrentSession().createCriteria(Item.class);
c2.add(c);//not correct parameter and trying to correct
List<Item> data = c2.list();
Above code is not correct. Please help me by giving right direction!

Jpa Criteria Table alias

Hi i'm struggling to write the following query with criteria api:
"SELECT c.id,curr.name FROM Cargo c, Currency curr"
The problem is that both Cargo and Currency are aliased as c by criteria so the resulting jpql becomes "SELECT c.id,c.name FROM Cargo c, Currency c".
I don't know if it is because both entities start with C.
Is there a way to chage the table alias?
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Tuple> query= criteriaBuilder.createTupleQuery();
Root<Cargo> cargo= query.from(Cargo.class);
Root<Currency> currency= query.from(Currency.class);
Any help is very much appreciated.
Your code is missing the part where you specify what you want selected. "SELECT c.id,curr.name FROM Cargo c, Currency curr"
would likely translate to something like:
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Tuple> query= criteriaBuilder.createTupleQuery();
Root<Cargo> cargo= query.from(Cargo.class);
Root<Currency> currency= query.from(Currency.class);
query.multiselect(cargo.get("id"), currency.get("name"));
Query query = em.createQuery(cq);
List<Tuple> results = query.getResultList();
There is an example here using only one table:
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Criteria#Tuple_Queries
After lots of debugging, i found out that the actual jpql that is executed is different from the one that is displayed in my ide(eclipse).
The aliases were ok.I think i was a bit deceived by the ide.
Thanks all for your attention.

Need help creating JPA criteria query

I'm building my first Java EE web application using Glassfish and JSF. I'm fairly new to the criteria query and I have a query I need to perform but the javaee6 tutorial seems a little thin on examples. Anyway, I'm having a hard time creating the query.
Goal: I want to pull the company with the most documents stored.
Companies have a OneToMany relationship with Documents.
Documents has a ManyToOne relationship with several tables, the "usertype" column distinguishes them.
MySQL query:
SELECT USERID, COUNT(USERID) AS CNT
FROM DOCUMENTS
WHERE USERTYPE="COMPANY"
GROUP BY USERID
ORDER BY CNT DESC
Thanks
--update--
Based on user feedback, here is what I have so far:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Documents> cqry = cb.createQuery(Documents.class);
//Intersting Stuff
Root<Documents> root = cqry.from(Documents.class);
Expression userid = root.get("userID");
Expression usertype = root.get("userType");
Expression count = cb.count(userid);
cqry.multiselect(userid, count);
Predicate userType = cb.equal(usertype, "COMPANY");
cqry.where(userType);
cqry.groupBy(userid);
cqry.orderBy(cb.desc(count));
//more boilerplate
Query qry = em.createQuery(cqry);
List<Documents> results = qry.getResultList();
The error I get is:
Exception Description: Partial object queries are not allowed to maintain the cache or be edited. You must use dontMaintainCache().
Typical error, means nothing to me!
Your query doesn't return a complete entity object as you're only selecting two fields of the given table (this is why you're getting an error that says yadayadapartialyadayada).
Your solution is almost right, here's what you need to change to make it work—making it partial.
Instead of a plain CriteriaQuery<...> you have to create a tuple CriteriaQuery<..> by calling CriteriaBuilder.createTupleQuery(). (Basically, you can call CriteriaBuilder.createQuery(...) and pass Tuple.class to it as an argument. Tuple is a sort of wildcard entity class.)
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq= cb.createTupleQuery();
Root<Documents> root = cq.from(Documents.class);
Expression<Integer> userId = root.get("USERID");
Expression<String> userType = root.get("USERTYPE");
Expression<Long> count = cb.count(userId);
cq.multiselect(userId.alias("USERID"), count.alias("CNT"));
cq.where(cb.equal(userType, "COMPANY");
cq.groupBy(userId);
cq.orderBy(cb.desc(count));
TypedQuery<Tuple> tq = em.createQuery(cq);
for (Tuple t : tq.getResultsList()) {
System.out.println(t.get("USERID"));
System.out.println(t.get("CNT"));
}
(Accessing fields of a Tuple gave me an error if I didn't use aliases for them (in multiselect(...)). This is why I've used aliases, but this can be tackled more cleanly by using JPA 2's Metamodel API, which is described in the specification quite thoroughly. )
The documentation for CriteriaQuery.multiselect(...) describes the behaviour of queries using Tuple objects more deeply.
If you are using Hibernate, this should work:
ProjectionList pl = Projections.projectionList()
.add(Projections.groupProperty("userid"))
.add(Projections.property("userid"))
.add(Projections.count("userid"));
Criteria criteria = session.createCriteria(Document.class)
.add(Restrictions.eq("usertype",usertype))
.setProjection(pl)
.addOrder(Order.desc("cnt"));
Hope it helps!
Take a look into this easy tutorial. It uses JPA2 and Criteria
http://www.jumpingbean.co.za/blogs/jpa2-criteria-api
Regards!
You need to add a constructor to Documents with only userid and count because you will need it on:
cqry.multiselect(userid, count);

Categories