How to implment hibernate IN clause with Criteria? - java

I'm working with hibernate to serach element into database.
I have yhis sql query to implement with hibernate.
select * from PRESence presence0
inner JOIN AgentMJ agentmj1_ on presence0.FK_AGENTMJ_ID=agentmj1_.PK_AGENTMJ_ID
where agentmj1_.PK_AGENTMJ_ID=18
and (presence0.typeContactLibre like 'Absence')
and agentmj1_.PK_AGENTMJ_ID
in (
select agentmj1_.PK_AGENTMJ_ID from AgentMJ agentmj1_
inner JOIN Absence absences2_ on agentmj1_.PK_AGENTMJ_ID=absences2_.FK_AGENT_MJ_ID
inner join TypeAbsence typeabsenc3_ on
absences2_.FK_TYPE_ABSENCE_ID=typeabsenc3_.PK_TYPE_ABSENCE_ID
where agentmj1_.PK_AGENTMJ_ID=18 and typeabsenc3_.code =1);
My problem is I can't implement the IN clause using hibernate.
How to do that? and there is an example to see it?Thanks in advance.

Related

Hibernate - Select all rows in a table

Im trying to get my query to load all rows in a table, im working with hibernate.
#Override
public List<Teacher> getTeachersBySubject(Subject subject) {
List<Teacher> teachersBySubject = entityManager.createQuery("SELECT * FROM teacher t INNER JOIN teacher_subject ts on t.email = ts.email")
.getResultList();
return teachersBySubject;
}
The * (All) Gives the error im dealing with, it won't load because of hibernate
the error that im getting is this : org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: * near line 1, column 8 [SELECT * FROM com.scalda.vos.models.Teacher t INNER JOIN teacher_subject ts on t.email = ts.email]
its not native and your writing hql so replace * with t.
You have written a native query, which must be compiled using the createNativeQuery method.
The createQuery expects HQL and not native SQL, and therefore to do it in HQL use just "teacher FROM Teacher". Also, if you are just retrieving a Teacher and not a Teacher-Subject hybrid then, Hibernate can also help you with retrieving associations check this
HIbernate expects you to use JPQL, it looks like SQL, but should be like this:
SELECT t FROM teacher t JOIN t.subject
Of course, it depends on how you Teacher class is annotated (ManyToMany, OneToMany mappings).
as my recommendation, use hql for clear code in hibernate or using criteria
but, still running well in native.
For native SQL, use createSqlQuery, like :
List<Teacher> teachersBySubject = entityManager.createSqlQuery("SELECT * FROM teacher t INNER JOIN teacher_subject ts on t.email = ts.email")
.getResultList();

Hibernate generates unneeded join clause and fails (migrating from 3.5.6 to 3.6.10)

We have a problem when trying to migrate hibernate from 3.5.6 to 3.6.10. We are using hbm.xml configuration files. Here is the criteria:
public List<Cat> findCats(Com com) {
DetachedCriteria criteria = DetachedCriteria.forClass(Occupe.class);
criteria.add(Restrictions.eq("com", com));
criteria.add(Restrictions.or(Restrictions.isNull("datLibPt"),
Restrictions.gt("datLibPt", Calendar.getInstance().getTime())));
criteria.add(Restrictions.isNull("delDate"));
criteria.createAlias("cat", "cat");
criteria.add(Restrictions.isNull("cat.delDate"));
criteria.addOrder(Order.asc("cat.csv"));
criteria.setProjection(Projections.property("cat"));
return findByCriteria(criteria);
}
With Hibernate 3.5.6, it generates the following query:
Hibernate: select this_.TRA_ID as y0_ from mydb..OCCUPE this_
inner join mydb..CAT cat1_ on this_.TRA_ID=cat1_.TRA_ID where this_.COM_ID=? and (this_.OCC_DAT_LIB_FCT is null or this_.OCC_DAT_LIB_FCT>?) and this_.DELDATE is null and cat1_.DELDATE is null order by cat1_.TRA_CSV asc
With Hibernate 3.6.10 it generates the following query:
select this_.TRA_ID as y0_ from mydb..OCCUPE this_
inner join mydb..CAT cat1_ on this_.TRA_ID=cat1_.TRA_ID
inner join mydb..CAT cat1_ on this_.TRA_ID=cat1_.TRA_ID where this_.COM_ID=? and (this_.OCC_DAT_LIB_FCT is null or this_.OCC_DAT_LIB_FCT>?) and this_.DELDATE is null and cat1_.DELDATE is null order by cat1_.TRA_CSV asc
and fails subsequently because of the (logical) error com.sybase.jdbc3.jdbc.SybSQLException: Tables 'mydb..CAT' and 'mydb..CAT' have same exposed names.
The 3.6.10 query is strictly similar to the 3.5.6 one except for the duplicated inner join statement. I am trying to understand this weird behavior. I think I am going to use a HQL request instead, but if you have any hint, don't hesitate to comment ;)

Left join on unrelated tables in Query DSL and JPA

I have two unrelated tables, each one with field email. I need a query which introduces column taken from second table if emails match or will be null if no match is found. In SQL this is easy:
SELECT tableA.id, tableA.email, tableB.name
FROM tableA
LEFT JOIN tableB ON tableA.email=tableB.email
ORDER BY tableB.name
Unfortunately JPA doesn't allow joins over unrelated entities so I converted it to:
SELECT tableA.id, tableA.email,
(SELECT tableB.name FROM tableB WHERE tableB.email=tableA.email) AS aname
FROM tableA
ORDER BY aname
Now, it works as JPA query but we are using Query DSL so off we go to converting it:
JPQLQuery query = new JPAQuery(em);
List<Dto> items=query.from(qTableA)
.list(new QDto(qTableA.id, qTableA.email,
new JPASubQuery().from(qTableB)
.where(qTableB.email.eq(qTableA.email)).unique(qTableB.name)))
It works but now I have no idea how to implement sorting and filtering by field introduced by subquery.
Dto is a POJO used to collect results, QDto is a class autogenerated from Dto.
Question is: how to join two unrelated tables using Query DSL and JPA and avoiding native SQL? Is it possible? Sorting and filtering on fields from tableA and tableB.name is a requirement.
Join on unrelated entities is not covered by latest JPA spec (2.1)
However Hibernate 5.1.0+ and EclipseLink 2.4.0+ support ad hoc joins. http://blog.anthavio.net/2016/03/join-unrelated-entities-in-jpa.html

Inner join using HQL

I am trying to inner join two tables on one column.
From DB side, there's no mapping as it's something I don't want to discuss.
I want to execute HQL query using INNER JOIN and retrieve ROLE objects/results.
Here's my hql so far
session.createQuery("from ROLE as role INNER JOIN INVOLVEMENT as involvement ON role.id = involvement.roleid WHERE involvement.id = X").list();
I see ON is not available on HQL. how do i explicitly tell Hibernate to JOIN on this column only.
I tried below one too
select roleSpec from ROLE as role, INVOLVEMENT as involvement WHERE role.ID = involvement.role_id and involvement.id =27251352
But I am getting ROLE not mapped in exception.
Please check that your ROLE is indeed a mapped entity.
In addition, you don't need to perform "ON" - hibernate knows what is the join column (I know how to define this at JPA ) - so no need to provide it at the statement.
It should be -
session.createQuery("from Role as role INNER JOIN Involvement as involvement WHERE involvement.id = X").list();
I assume you have Role class mapped to ROLE table, and Involvement class mapped to Involement table.
Maybe you used table names by mistake, and this is why you get the "not mapped" error.
Last time I wrote HQL (and not JPA-QL) I used the following link as reference, it provides all the info needed.

Using sub queries in Hibernate

Consider a sample query which uses two tables. Query would be like:
select t1.name, t1.address, (select count(*) from table2 t2 where t1.userid = t2.userid) as totalpoints from table1 t1
There are two bean classes named Table1.java and Table2.java. My DAO class extends HibernateDAOSupport. Is it possible to use this query with the two bean class in getHibernateTemplate.find() function call?
Any help would be appreciable.
Thanks.
Yes, it's possible. The HQL query will be nearly identical to the SQL query. Note that your SQL is invalid, though. There is even an example of such a query in the Hibernate documentation about subqueries.

Categories