-->
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.  [ 4 posts ] 
Author Message
 Post subject: specifying join behavior for associated classes
PostPosted: Mon Nov 14, 2005 3:41 pm 
Beginner
Beginner

Joined: Tue Sep 23, 2003 10:03 am
Posts: 26
Location: madison, wi
Hibernate version: 3.0.5

Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-lazy="false">
   <class name="com.test.Style" table="Style">
      <id name="id" unsaved-value="null">
         <generator class="native" />
      </id>
      <property name="description"/>
      <many-to-one name="season" class="com.test.ListItem" cascade="none"/>
   </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
Code:
   List results = getSession().createQuery("select style from Style style  where style.season.displayName like '%fall%' or style.description like '%10%' order by style.styleNumber").list();
   System.out.println(results.size());


Full stack trace of any exception that occurs:No errors.

Name and version of the database you are using:MS SQL server 2000 sp4

The generated SQL (show_sql=true):
Code:
select style0_.id as id, style0_.description as descript6_169_,  from Style style0_, CollectiveListItems collective1_ where (collective1_.displayName like '%fall%' and style0_.season=collective1_.id)or(style0_.description like '%10%' )



I feel like quite the noob for this, but this is returning way too many results (for me, about 86000 rather than 2000). Adding a "distinct" to the hql query gets the right number, but it's horribly inefficient and takes nearly 10 seconds. From what I see, the expression " and style0_.season=collective1_.id" should be a condition of the join, so that the generated sql should look like this:

Code:
select style0_.id as id, style0_.description as descript6_169_,  from Style style0_, CollectiveListItems collective1_ where style0_.season=collective1_.id and  (collective1_.displayName like '%fall%' or style0_.description like '%10%' )


Even this would be equivalent and work just as well for me:
Code:
select style0_.id as id, style0_.description as descript6_169_,  from Style style0_, CollectiveListItems collective1_ where (collective1_.displayName like '%fall%' and style0_.season=collective1_.id)or(style0_.description like '%10%' and style0_.season=collective1_.id)



That is a fast query and is what I want to do. I've been reading about joins, and have experimented with fetch="select|join" and haven't had any luck. What am I missing here?

The other option I can think of right now is to change the HQL query to something like this:
Code:
select style from Style style, ListItem listItem where style.season = listItem AND (listItem.displayName like '%fall%' or style.description like '%10%')


That works, and in an acceptable amount of time, but these queries are assembled at runtime through an advanced search type interface, so coming up with that HQL on the fly is a lot harder, but not impossible. Any ideas?

Thanks for looking.


Top
 Profile  
 
 Post subject: 2c
PostPosted: Mon Nov 14, 2005 5:36 pm 
Expert
Expert

Joined: Fri Jul 22, 2005 2:42 pm
Posts: 670
Location: Seattle, WA
Quote:
"select style from Style style where style.season.displayName like '%fall%' or style.description like '%10%' order by style.styleNumber"



The second condition [style.description like '%10%'] does not require presence of collection elements and therefore Hibernate’s translation to SQL seems logical and correct.

Note: your fast query will not pick Styles which do not have associated collection elements; that maybe OK or not depending on your requirements.

Therefore your last HQL seems like way to go.

Or you can use SQL support in Hibernate
http://www.hibernate.org/hib_docs/v3/re ... rysql.html

_________________
--------------
Konstantin

SourceLabs - dependable OpenSource systems


Top
 Profile  
 
 Post subject: Re: 2c
PostPosted: Tue Nov 15, 2005 10:52 am 
Beginner
Beginner

Joined: Tue Sep 23, 2003 10:03 am
Posts: 26
Location: madison, wi
kgignatyev wrote:
Quote:
"select style from Style style where style.season.displayName like '%fall%' or style.description like '%10%' order by style.styleNumber"



The second condition [style.description like '%10%'] does not require presence of collection elements and therefore Hibernate’s translation to SQL seems logical and correct.

I'm not a database whiz, so pardon me if I sound like a clod here. When I do something like "where style.season.displayName like '%fall%'" I would expect that hibernate would do an inner join here. Is there any way to make hibernate do an inner join in that case? I know I can force hibernate to do an inner join in the HQL, as shown below and in my solution in the OP. Is there a way to force hibernate to do an inner join in the mapping document? I just don't understand why, in an association like this, an outer join would ever be desired or useful. I realized that my lack of understanding may be indicative of my lack of DB knowledge, but I'd like to know.
Quote:

Note: your fast query will not pick Styles which do not have associated collection elements; that maybe OK or not depending on your requirements.

Therefore your last HQL seems like way to go.

Or you can use SQL support in Hibernate
http://www.hibernate.org/hib_docs/v3/re ... rysql.html


Thanks for the comments. I think what I really want to do is something along these lines:

Code:
select style from Style style join style.season season where season.displayName like '%fall%' or style.description like '%10%')


This is roughly equivalent to the last HQL query in my first post. It's a lot less code to write, though, since I don't have to know that the season is in the ListItem table when I construct the query.


Top
 Profile  
 
 Post subject: Re: 2c
PostPosted: Tue Nov 15, 2005 12:34 pm 
Expert
Expert

Joined: Fri Jul 22, 2005 2:42 pm
Posts: 670
Location: Seattle, WA
thechrisproject wrote:
kgignatyev wrote:
Quote:
"select style from Style style where style.season.displayName like '%fall%' or style.description like '%10%' order by style.styleNumber"



The second condition [style.description like '%10%'] does not require presence of collection elements and therefore Hibernate’s translation to SQL seems logical and correct.

I'm not a database whiz, so pardon me if I sound like a clod here. When I do something like "where style.season.displayName like '%fall%'" I would expect that hibernate would do an inner join here. Is there any way to make hibernate do an inner join in that case?


And Hibernate does the join for this condition that comes first in your query, I was pointing at the second condition, which does not require join anyhow.

The query result is kind union of two queries:
select style.* from Style style where style.season.displayName like '%fall%'
UNION
select style.* from Style style where style.description like '%10%'

_________________
--------------
Konstantin

SourceLabs - dependable OpenSource systems


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