Hibernate versions used:
Code:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.5.5-Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.5.5-Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
Let's say there are two cats ( cat and its mate that have the same kittens )
cat/cat's mate has a relationship with it's kittens with kitten's name as join column (OneToMany relationship on join column with a fetch type "eager" )
Let's say I want to get the cats where it's kitten's name is "big", for which, I can write hql in a different ways.
I.
Code:
hql.append("from Cat as cat ")
hql.append("where cat.kitten.name = 'big' ");
II.
Code:
hql.append("from Cat as cat inner join cat.kitten as kitten ")
hql.append("where kitten.name = 'big' ");
The aforementioned hql's generate an inner join between cat and it's kitten and is working as expected.
But, if I want to query on a property in kitten with which cat is not joined to kitten ( say location ), I can write hql as follows:
III.
Code:
hql.append("from Cat as cat ")
hql.append("where cat.kitten.location = 'Chicago' ");
IV.
Code:
hql.append("from Cat as cat inner join cat.kitten as kitten ")
hql.append("where kitten.location = 'Chicago' ");
Question 1)
III and IV are working as expected as well, but, the III is generating cartesian/cross join between cat and it's kitten without an explicit join mentioned in the hql, whereas, IV is not. Why is that?
And
Say, I want to join two "different" objects cat and mate in hql ( which doesn't have any association ) on mate's name, it is generating cross joins.
For instance, if I say,
V.
Code:
hql.append("select cat ")
hql.append("from Cat as cat, Mate mate ")
hql.append("where cat.location = mate.location and mate.location = 'Chicago' ");
It generates cross join.
But, if I say,
VI.
Code:
hql.append("from Cat as cat ")
hql.append("where cat.location in ( select mate.location from Mate mate where mate.location = 'Chicago' ");
Question 2)
It doesn't generate a cross join. But, what if I had to use two columns. I need to use two in clauses to not have a cross join generated by hql. Why does it have to be explicit? or Is there a hibernate configuration to say avoid cross joins if possible?