-->
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.  [ 9 posts ] 
Author Message
 Post subject: Multiple Queries on many-to-one (not a "lazy" prob
PostPosted: Fri Aug 27, 2004 2:29 pm 
Newbie

Joined: Fri Aug 27, 2004 1:52 pm
Posts: 9
Hibernate 2.1.6

MySQL 4.0.20

Would someone please explain to my why when doing a query on an object with only many-to-one relationships, why multiple queries are required to retrieve the objects?

For instance if I had the following mapping file (below) and I issues a simple query like "from ForumTopic" hibernate does one query to get all the ForumTopics, but then issues a separate query for the Topic for every row of the Forums, when it could easily join the tables on one query. This has a multiplicative effect when you have many-to-one relationships in Topic.

I'm not talking about wanting lazy initialization. I want all the information, I just want it done in one query as it should be, rather than tons of them. Am I doing anything wrong? This is a make or break decision for me to use hibernate.

<class name="ForumTopic" table="THE_DB.F_FORUM_TOPIC">
<id name="id" type="long" column="FORUM_TOPIC_OID">
<generator class="hilo">
<param name="table">HI_VALUE</param>
<param name="column">NEXT_VALUE</param>
<param name="max_lo">1000</param>
</generator>
</id>
<many-to-one name="topic" column="TOPIC_OID" outer-join="true"/>
</class>

<class name="Topic" table="THE_DB.T_TOPIC">
<id name="id" type="long" column="TOPIC_OID">
<generator class="hilo">
<param name="table">HI_VALUE</param>
<param name="column">NEXT_VALUE</param>
<param name="max_lo">1000</param>
</generator>
</id>
<property name="topicClosed" column="IS_TOPIC_CLOSED" type="boolean"/>
<property name="topicArchived" column="IS_TOPIC_ARCHIVED" type="boolean"/>
<property name="topicLead" column="TOPIC_LEAD" type="string"/>
</class>


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 27, 2004 3:35 pm 
Regular
Regular

Joined: Tue Dec 09, 2003 2:39 pm
Posts: 106
Location: Toronto, Canada
You're right, this isn't necessarily a "lazy" problem. Check out 11.3 in the Hibernate docs, Associations and Joins.

I think you'll want to modify your query to look something like:

Code:
"from ForumTopic as forumTopic left join forumTopic.topic as topic"


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 27, 2004 3:38 pm 
Regular
Regular

Joined: Tue Dec 09, 2003 2:39 pm
Posts: 106
Location: Toronto, Canada
Also noticed that you don't have the class attribute in your many-to-one mapping. Should include

<many-to-one name="topic" column="TOPIC_OID" class="Topic" outer-join="true"/>


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 27, 2004 3:40 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
That doesn't matter, Hibernate will use reflection to determine the class. More interesting would be _how_ the ForumTopic is loaded. Much better would be if the questions in the RED BOX would be answered, so we can see whats going on.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 27, 2004 3:45 pm 
Regular
Regular

Joined: Tue Dec 09, 2003 2:39 pm
Posts: 106
Location: Toronto, Canada
christian wrote:
That doesn't matter, Hibernate will use reflection to determine the class...


Right, my bad.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 27, 2004 6:02 pm 
Newbie

Joined: Fri Aug 27, 2004 1:52 pm
Posts: 9
Thanks for the quick replies guys. That helps a lot.

However, there's one situation where I'm still having problem: In cases where I've set up a proxy object. For instance if I had defined Topic with proxy="Topic" then it waits until a property of the object is retreived until it does the query even if I specify a left join in the query. For the most part, I'd like to define all my ojbects with proxies to prevent unintended querying from the database, but I'd like to still be able to override that when I know I want all the data.

Is there any way to do this?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 27, 2004 6:04 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
This is all guessing, unless you show the code, the mapping, the log, and state the problem you are having with this particular case.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 27, 2004 7:04 pm 
Newbie

Joined: Fri Aug 27, 2004 1:52 pm
Posts: 9
Sorry for the lack of detail. I figured out the problem. I'll detail it here to see if this makes sence.

Assume I have the exact same mapping files above with the addition of proxy="Topic" for the topic class. If I use the code below then it will create one query for the initial query, and another query to get the Topic for each call to isTopicClosed().

Code:
        Query q = s.createQuery("from ForumTopic ft left join ft.topic t");
        List<ForumTopic> l = q.list();
        for (ForumTopic ft : l) {
            boolean b = ft.getTopic().isTopicClosed();
        }



However, if I add a select clause and explicityly call out getting the topic object then it works fine. It just requires a little extra work getting the objects out that you want, since it wraps them in an object array;

Code:
       Query q = s.createQuery("Select ft, t from ForumTopic ft left join ft.topic t");
        q.setFirstResult(0);
        q.setMaxResults(5);
        List<Object[]> l = q.list();
        for (Object[] o : l) {
            ForumTopic ft = (ForumTopic) o[0];
            boolean b = ft.getTopic().isTopicClosed();
        }


btw: the new Generics in Java 1.5 seem to work find with Hibernate which makes me very happy. ;-) Thanks again!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 27, 2004 11:53 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Code:
Query q = s.createQuery("from ForumTopic ft left join [b]fetch[/b] ft.topic t");


HQL queries ignore the mapping fetching strategy.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


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