-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: LEFT JOIN use: WHERE inside of childs collection's mapping
PostPosted: Mon Jan 15, 2007 10:24 am 
Newbie

Joined: Wed May 31, 2006 12:58 pm
Posts: 14
Hello everybody,

I have the following problem:

There is a parent class (let's name it "PARENT") which has a one-to-many relationship to a child class (let's name such a class as "CHILD"). So, a PARENT instance contains a Collection with CHILDs (let's name the collection class property as "childs").

Such a collection is specified in the Hibermnate-config file for PARENT like the following:
Code:
<bag name="childs" inverse="true" cascade="none" access="field"
         where="<<HUGE CONDITION>>" >
    <key column="SOURCE_ID" />
     <one-to-many class="CHILD" />
</bag>


A PARENT may have no CHILDs such that there is no corresponding rows in the CHILD-related DB table at all or there are some rows, but they are not considrered because of 'WHERE' in the mapping.

I need to produce an HQL query which will return in each result "row" some details about a PARENT along with details of a corresponding CHILD (if any). Logically, a LEFT JOIN is a solution. Something like:
Code:
select p.key, ch.key
from PARENT p
left join p.childs as ch


But the 'WHERE' in the mapping prevents such a LEFT JOIN: if no CHILDs exists for a PARENT (taking the 'WHERE' into consideration), then nothing is returned (not just 'NULL' in place of 'ch.key'). I know such a "WHERE-influenced" logic for HQL joins, so it looks like not an extraordinary thing.

But I would need to write a query which delivers NULLs in place of CHILDs data if it does not exist. The WHERE condition can not be eliminated from mapping. Are there any ways to get what I want?

Thanks in advance,
Andrew


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 1:48 pm 
Newbie

Joined: Sat Jan 13, 2007 7:04 pm
Posts: 5
I have the same problem. I'm new to hibernate as of a couple days ago.

I'm using a regular SQL query instead of a HQL query.

The only problem is that I can't get the results out of q.list(). It keeps telling me the object cannot be cast.

Basically, what I want to do is create a join that automatically populates the children in the parent class if they exist. For example, my parent class has a "public Set getChildren()" method that lazy loads the children when called. I want to create X parent class instances and pre-load that Set with children(if they exist) using a left join.

Matt


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 1:53 pm 
Newbie

Joined: Wed May 31, 2006 12:58 pm
Posts: 14
But I need an HQL query, no SQL...


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 3:08 pm 
Newbie

Joined: Sat Jan 13, 2007 7:04 pm
Posts: 5
I almost have it using HQL

The basic part of my query is this. The key is the "fetch" keyword.

Code:
from Parent p left outer join fetch p.children as c


That seems to have populated the classes but in a strange way. Every parent gets all the children, even if they are not related by the join. The query executed by Hibernate manually returns the correct results, in my case 4 rows. But when I do something like this:


Code:
//psuedo code
for (Parent p : parents) {
    for (Child c: p.getChildren()) {
        print c.name();
    }
}


It would print something like
Code:
Parent 1
   peter
   paul
   mary
Parent 2
   peter
   paul
   mary


When the real relationship is
Code:
Parent 1
   peter
Parent 2
   paul
   mary


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 4:09 pm 
Newbie

Joined: Sat Jan 13, 2007 7:04 pm
Posts: 5
I fixed from something I found in the faq. It doesn't seem right though. The query returns 4 rows, yet when I print it out, its 13 rows.

I added this:
Code:
Collection results = new HashSet(s.createQuery(query).list());
return results;


That works but, with the possibility of thousands of rows being returned, how long is it going to take it to filter out the duplicates that it seems to create on its own?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 4:38 pm 
Newbie

Joined: Sat Jan 13, 2007 7:04 pm
Posts: 5
Nm, I see why. Every row is a join between the child and parent, so you have duplicate references to the same parent.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 5:04 pm 
Newbie

Joined: Sat Jan 13, 2007 7:04 pm
Posts: 5
This should work:

Code:
Session s = getSession();
uery q = s.createQuery("from Parent p left outer join fetch p.children as c");
q.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
return q.list();


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.