Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HQL left join of un-related entities

I have 2 entities, A and B. They are related but I do not want to add the relationship mapping to the beans.

How can we use left outer join between A and B using HQL or criteria?

There are some workarounds available for this,

  1. Use Native SQL as told here.
  2. Add a relationship and use select a from A a left join a.b.
  3. We can do a inner join in the HQL as select * from A a, B b where a.some=b.some

I was always going back these 2 options, is there any alternative for this? Or this in not possible?

like image 856
ManuPK Avatar asked Mar 27 '12 14:03

ManuPK


People also ask

How do you join unrelated entities in hibernate?

The only way to join two unrelated entities with JPA 2.1 and Hibernate versions older than 5.1, is to create a cross join and reduce the cartesian product in the WHERE statement. This is harder to read and does not support outer joins. Hibernate 5.1 introduced explicit joins on unrelated entities.

How do I write a left join in HQL?

select * from A as a left join B as b on a.id = b.id left join C as c on b. type=c.

Can we use join in HQL query?

Some of the commonly supported clauses in HQL are: HQL From: HQL From is same as select clause in SQL, from Employee is same as select * from Employee . We can also create alias such as from Employee emp or from Employee as emp . HQL Join : HQL supports inner join, left outer join, right outer join and full join.

Is join Default left join?

Bookmark this question. Show activity on this post. LEFT JOIN is not equal to JOIN . The default JOIN is INNER .


2 Answers

Currently, the theta-style on joining the unrelated classes in the where clause using HQL only supports inner join.

The request for supporting the outer join for such situation is currently the 3-rd most voted enhancement but I don't think this feature will be implemented in the near feature as it requires the re-implementation of the current ANTLER-based query parser first which seems to be a gigantic task IMO.

If you insist to use the HQL to perform left join without adding the relationship between A and B , you can use option 3 to do the inner join first, then use the following HQL

from A a where a.some not in ( select b.some from B) 

to find out all the A that cannot join B and combine the results programmatically .

Update

As of release 5.1.0 HHH-16 (Explicit joins on unrelated classes) is fixed and we should be able to join the unrelated entities.

like image 175
Ken Chan Avatar answered Sep 18 '22 13:09

Ken Chan


As Ken Chan said, you can't do it directly in a single HQL query.

Concerning your three possibilities:

  1. Native SQL: Not recommendable. The syntax for outer joins is quite different between different databases.
  2. Add a relationship: That's what I would do. It does not cost much code or memory and it is quickly programmed.
  3. Inner join: That does not work (missing rows) if the relation really is an outer join in the database.

If by any special reasons you really don't want to add the relationship, you can split the query into two individual queries and join the result manually in java, for example like this:

Query qa = session.createQuery("from A a"); List la = qa.list();  Query qb = session.createQuery("select distinct b.* from B b, A a where a.some=b.some"); List lb = qb.list();  Map bMap = new HashMap(); for (B b : lb) {   bMap.put(b.getId(), b); }  /* example with for loop */ for (A a : la) {   B b = bMap.get(a.getForeignKeyForB());   /* now you have A a and the outer joined B b and you can do with them what you want */   ... } 

This solution has (nearly) the same cost in execution time and memory as the outer join in the database (solution 2.). It is just a little bit more java code.

(The solution is similar to that one proposed by Ken Chan, but it avoids the "not in" and the inner select, which both can be inefficient in the database.)

like image 39
Johanna Avatar answered Sep 19 '22 13:09

Johanna