Consider the below queries to find all children of an entity:
The following would therefore result in just a Cartesian Product.
This kind of a cartesian product join is rarely of any use. However the ability to join two unrelated tables is needed. Consider the case where we need all Master and Child pairs that have the same identifier value.
public static void testGetEntityChild() { final Session session = sessionFactory.openSession(); Query q = session.createQuery("Select c from Entity e, Child c where e = c.parent"); List<Child> children = q.list(); System.out.println(children); q = session.createQuery("Select c from Entity e join e.children c "); children = q.list(); System.out.println(children); session.close(); }The output of the above is as below:
Hibernate:
/* Select
c
from
Entity e,
Child c
where
e = c.parent */
select
child1_.ID as ID2_,
child1_.`KEY` as KEY2_2_,
child1_.ENTITY_ID as ENTITY3_2_
from
ENTITY entity0_,
CHILD_ENTITY child1_
where
entity0_.ID=child1_.ENTITY_ID
[[Child] : ( id 1 , key : 1001 , parent.Id : 1 )], [Child] : ( id 2 , key : 1001
, parent.Id : 1 )]]
Hibernate:
/* Select
c
from
Entity e
join
e.children c */
select
children1_.ID as ID2_,
children1_.`KEY` as KEY2_2_,
children1_.ENTITY_ID as ENTITY3_2_
from
ENTITY entity0_
inner join
CHILD_ENTITY children1_
on entity0_.ID=children1_.ENTITY_ID
[[Child] : ( id 1 , key : 1001 , parent.Id : 1 )], [Child] : ( id 2 , key : 1001
, parent.Id : 1 )]]
AS we can see both the HQL statements generate different queries. The second query is an explicit inner join between entity and children. What about the first then. It is no implicit join.It is actually a cartesian product of all records in entities and children on which a where clause was applied restricting the final set.The following would therefore result in just a Cartesian Product.
final Session session = sessionFactory.openSession(); Query q = session.createQuery("Select c from Entity e, Child c"); List<Child> children = q.list(); System.out.println(children);Output:
Hibernate:
/* Select
c
from
Entity e,
Child c */
select
child1_.ID as ID2_,
child1_.`KEY` as KEY2_2_,
child1_.ENTITY_ID as ENTITY3_2_
from
ENTITY entity0_,
CHILD_ENTITY child1_
[[Child] : ( id 1 , key : 1001 , parent.Id : 1 )], [Child] : ( id 1 , key : 1001
, parent.Id : 1 )], [Child] : ( id 2 , key : 1001 , parent.Id : 1 )], [Child] :
( id 2 , key : 1001 , parent.Id : 1 )]]
As can be seen all combinations of child and entity were returned.This kind of a cartesian product join is rarely of any use. However the ability to join two unrelated tables is needed. Consider the case where we need all Master and Child pairs that have the same identifier value.
public static void testThetaStyleJoin() { final Session session = sessionFactory.openSession(); Query q = session.createQuery("from Master m, Child c where m.id = c.id"); List<Object[]> objects = q.list(); for (Object[] object : objects) { System.out.println(object[0] + " and " + object[1]); } session.close(); }The output is as below:
Hibernate:
/*
from
Master m,
Child c
where
m.id = c.id */
select
master0_.ID as ID1_0_,
child1_.ID as ID2_1_,
master0_.DATA as DATA1_0_,
child1_.`KEY` as KEY2_2_1_,
child1_.ENTITY_ID as ENTITY3_2_1_
from
ENTITY_MASTER master0_,
CHILD_ENTITY child1_
where
master0_.ID=child1_.ID
[Master] : ( id 1 , data : master No 1 )] and [Child] : ( id 1 , key : 1001 , pa
rent.Id : 1 )]
Such joins are called theta style joins - a cartesian product + a where condition to restrict the result.
No comments:
Post a Comment