-->
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.  [ 13 posts ] 
Author Message
 Post subject: join fetch
PostPosted: Fri Oct 21, 2005 1:41 pm 
Regular
Regular

Joined: Thu Sep 23, 2004 11:53 am
Posts: 83
Hibernate version: 3.1

Mapping documents:
state mapping
Code:
      <set name="counties" inverse="true">
            <key>
                <column name="STATE_CODE" length="2" not-null="true" />
            </key>
            <one-to-many class="com.County" />
        </set>


county mapping
Code:
        <many-to-one name="state" class="com.State" update="false" insert="false">
            <column name="STATE_CODE" length="2" not-null="true" />
        </many-to-one>

Code between sessionFactory.openSession() and session.close():
Code:
List results = SessionFactory.currentSession().createQuery("FROM State s join fetch s.counties WHERE s.stateCode = '42'").list();
      System.out.println(results.size());

Full stack trace of any exception that occurs:
NA
Name and version of the database you are using:
MySQL
The generated SQL (show_sql=true):
NA
Debug level Hibernate log excerpt:
NA

How come when ever I use the follwing query I get 277 State objects returned in the list ...

"FROM VsiState s join fetch s.vsiCounties WHERE s.stateCode = '42'"

but when I use this query..

"FROM VsiState WHERE s.stateCode = '42'"

I get what I expect, one State. From my understanding joing fetch tells hibernate to eagerly retrieve the counites instead of the default lazy fetching defined in the mapping file. So, my question is ... why is join fetch causing Hibernate to return 277 State objects when all I want is one State object with its counties already (eagerly) fetch.? How do I fix this?

Thanks for any help :)


Top
 Profile  
 
 Post subject: Re: join fetch
PostPosted: Fri Oct 21, 2005 1:50 pm 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
My guess is that since you're joining to the County object, there are 277 counties in the table with StateId 42. (Seems odd since I'm pretty sure no state has that many counties, but I digres)

Are the state objects all the same ? Sometimes Join queries require you to put the results into a Set to remove the duplicates. Using the Criteria API, you can set the ResultTransformer - ResultTransformer.DISTINCT_ROOT_ENTITY - so that only distinct objects are returned.

_________________
Preston

Please don't forget to give credit if/when you get helpful information.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 2:00 pm 
Regular
Regular

Joined: Thu Sep 23, 2004 11:53 am
Posts: 83
Well I looked at the resulting list (really kind of a spot check), and all the values are the same. I have no idea why?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 2:06 pm 
Beginner
Beginner

Joined: Tue Aug 23, 2005 3:52 pm
Posts: 26
Your HQL query "FROM VsiState s join fetch s.vsiCounties WHERE s.stateCode = '42" asks hibenate to return list of state and country objects. If you want only state objects you should change your query to "select c FROM VsiState s join fetch s.vsiCounties c WHERE s.stateCode = '42


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 2:07 pm 
Beginner
Beginner

Joined: Tue Aug 23, 2005 3:52 pm
Posts: 26
correction:
select s FROM VsiState s join fetch s.vsiCounties WHERE s.stateCode = '42


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 2:11 pm 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
noone wrote:
Well I looked at the resulting list (really kind of a spot check), and all the values are the same. I have no idea why?



If you're positive you're only expecting 1 State object, you can use Query.uniqueResult() instead of List.

Otherwise do this after you get your results.

Set states = new HashSet(results); Make sure that your State.hashCode() method is implemented properly.

BTW: Leonid's query won't change the results.

_________________
Preston

Please don't forget to give credit if/when you get helpful information.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 2:25 pm 
Regular
Regular

Joined: Thu Sep 23, 2004 11:53 am
Posts: 83
Your right that did not work, and I understnad that I could use uniqueResult but I just ran this query ...

"SELECT s FROM VsiState s join fetch s.vsiCounties WHERE s.stateCode = '42' OR s.stateCode = '03'"


and I received 352 entries ... 75 for state 03 and 277 for state 42 so this will not work.

It seems from the examples that join fetch is only supposed to return 1 object for the first query and 2 for the one I just ran above.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 2:46 pm 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
Set states = new HashSet(results);

Make sure that your State.hashCode() method is implemented properly.

_________________
Preston

Please don't forget to give credit if/when you get helpful information.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 3:04 pm 
Regular
Regular

Joined: Thu Sep 23, 2004 11:53 am
Posts: 83
Truely, if that ends up being the correct way to it then I will create the Set, but it seems odd that I would have to create Set for this situtation when it is returning the same 277 State objects for state '42'. I think either there is something wrong with the mapping or something wrong with the query, but which one it is and whats the best path to resolving the problem I don't know.

Is there something wrong with the mapping? Something wrong with the query? I am not sure. The examples shows this is poosible ...


from Cat as cat
inner join fetch cat.mate
left join fetch cat.kittens

and that this should return Cat objects, one for each unique Cat. So if there where 5 cats and 5 Kittens per Cat, then there should be 5 Cat objects in the resulting list not 25 Cat objects. :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 3:34 pm 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
I was just providing you with the information that I've seen over the past few months from the Hibernate guys..

Christain - http://forum.hibernate.org/viewtopic.ph ... et+results

Anthony - http://forum.hibernate.org/viewtopic.ph ... ts+hashset

Gavin - http://forum.hibernate.org/viewtopic.ph ... ts+hashset

"This is known and intended behaviour (though contraversial). Applying DISTINCT in memory can be a quite expensive operation, so we prefer to leave it to the application. Just add the query results to a hashset and you will be fine...."

_________________
Preston

Please don't forget to give credit if/when you get helpful information.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 3:40 pm 
Regular
Regular

Joined: Thu Sep 23, 2004 11:53 am
Posts: 83
Wow, that pretty much answer my question, surprised though. Some of the posts in the links said wait for Hibernate 3 or 3.1 ... has it changed any?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 3:45 pm 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
noone wrote:
Wow, that pretty much answer my question, surprised though. Some of the posts in the links said wait for Hibernate 3 or 3.1 ... has it changed any?


I haven't seen any change. Maybe someone could correct me if there has been.

The only time I have issues with the behavior is when you want to limit your results to say the first 20 States or whatever. Since the Limit ends up on the SQL statement, and the SQL Statement returns the JOINED results, you might not actaully get more than 1 actual State object.

_________________
Preston

Please don't forget to give credit if/when you get helpful information.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 21, 2005 4:11 pm 
Regular
Regular

Joined: Thu Sep 23, 2004 11:53 am
Posts: 83
Thanks, from what it seems this nullifies using "fetch" and forcing the change to be in the mapping, which according to the documentation suggest not altering the mapping, but using "fetch" in the query (or setting the fetch mode for Criteria searches). This is an Object relational mapping tool and in that respects, to me Hibernate should return the results as unique Cat objects or in my case unique State objects. If the user decides to setRowMax (which is a JDBC ... relational setting) then, maybe make a note in the documentation that by doing so will return incomplete objects. Beside when I execute this....

FROM State WHERE code = '42'

Does this not give one State object with 277 counties in it? Maybe that should be a hint as to what this should return ...

FROM State as s join fetch s.counties WHERE code = '42'

... since fetch is only suppose to eagerly retrieve the association!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 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.