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