-->
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.  [ 6 posts ] 
Author Message
 Post subject: HQL Generating incorrect SQL for outer left joins
PostPosted: Mon Feb 14, 2011 6:33 am 
Newbie

Joined: Mon Jan 24, 2011 5:54 am
Posts: 4
Hi,

We have recently upgraded our application from 3.0.5 to 3.5.5-FINAL and have found an error with the SQL being generated.

We have a simple class with two subclasses.
On the supertype is a 0..1 association to an entity holding error status (Most of the time this will be empty) and used to filter out those entities who have an error and are to be ignored.

The HQL query used is this:
Code:
            select distinct billableParty from com.wcg.wsf.billing.BillableParty billableParty
            left join billableParty.processRunnableStatus
            where billableParty.lineOfBusiness.id = :lineOfBusinessId
            and (billableParty.processRunnableStatus is null OR billableParty.processRunnableStatus.ignored = 0)


With 3.5.5 it is generating the following SQL for this query:
Code:
select distinct billablepa0_.ID as ID237_,
billablepa0_.VERSION as VERSION237_,
billablepa0_.LINE_OF_BUSINESS_FK as LINE3_237_,
billablepa0_.PROCESS_RUNNABLE_STATUS_ as PROCESS4_237_ ,
case when billablepa0_1_.ID is not null then 1 when billablepa0_2_.ID is not null then 2 when billablepa0_.ID is not null then 0 end as clazz_
from BILLABLE_PARTY billablepa0_, DLR_BILLABLE_PARTY billablepa0_1_, SUP_BILLABLE_PARTY billablepa0_2_, PROC_RUN_STATUS processrun1_, PROC_RUN_STATUS processrun2_
where billablepa0_.ID=billablepa0_1_.ID(+)
and billablepa0_.ID=billablepa0_2_.ID(+)
and billablepa0_.PROCESS_RUNNABLE_STATUS_=processrun1_.ID(+)
and billablepa0_.PROCESS_RUNNABLE_STATUS_=processrun2_.ID
and billablepa0_.LINE_OF_BUSINESS_FK=2006285483720750007
and (billablepa0_.PROCESS_RUNNABLE_STATUS_ is null or processrun2_.IGNORED=0)

This is incorrectly returning no results.

Going back to a 3.0.5 version of our app and running on the same database, the following SQL used to be generated:
Code:
select distinct billablepa0_.ID as ID, billablepa0_.version as version222_, billablepa0_.LINE_OF_BUSINESS_FK as LINE3_222_, billablepa0_.PROCESS_RUNNABLE_STATUS_ as PROCESS4_222_,
case when billablepa0_1_.ID is not null then 1 when billablepa0_2_.ID is not null then 2 when billablepa0_.ID is not null then 0 end as clazz_
from BILLABLE_PARTY billablepa0_
left outer join DLR_BILLABLE_PARTY billablepa0_1_ on billablepa0_.ID=billablepa0_1_.ID
left outer join SUP_BILLABLE_PARTY billablepa0_2_ on billablepa0_.ID=billablepa0_2_.ID
left outer join PROC_RUN_STATUS processrun1_ on billablepa0_.PROCESS_RUNNABLE_STATUS_=processrun1_.ID
where billablepa0_.LINE_OF_BUSINESS_FK=2006285483720750007
and (billablepa0_.PROCESS_RUNNABLE_STATUS_ is null or processrun1_.IGNORED=0)


This returned the results as expected.

Examining the 3.5.5 query closer I noticed that there is a missing (+) that should be on the second "and billablepa0_.PROCESS_RUNNABLE_STATUS_=processrun2_.ID
"
so the correct query SHOULD actually be:
Code:
select distinct billablepa0_.ID as ID237_,
billablepa0_.VERSION as VERSION237_,
billablepa0_.LINE_OF_BUSINESS_FK as LINE3_237_,
billablepa0_.PROCESS_RUNNABLE_STATUS_ as PROCESS4_237_ ,
case when billablepa0_1_.ID is not null then 1 when billablepa0_2_.ID is not null then 2 when billablepa0_.ID is not null then 0 end as clazz_
from BILLABLE_PARTY billablepa0_, DLR_BILLABLE_PARTY billablepa0_1_, SUP_BILLABLE_PARTY billablepa0_2_, PROC_RUN_STATUS processrun1_, PROC_RUN_STATUS processrun2_
where billablepa0_.ID=billablepa0_1_.ID(+)
and billablepa0_.ID=billablepa0_2_.ID(+)
and billablepa0_.PROCESS_RUNNABLE_STATUS_=processrun1_.ID(+)
and billablepa0_.PROCESS_RUNNABLE_STATUS_=processrun2_.ID(+)
and billablepa0_.LINE_OF_BUSINESS_FK=2006285483720750007
and (billablepa0_.PROCESS_RUNNABLE_STATUS_ is null or processrun2_.IGNORED=0)

Using the SQL directly returns the result I expect.

But this means that the latest Hibernate is not generating the correct SQL.
Anyone else encountered this error?
Is there an easy fix? We have a large application and manually finding and changing all queries will be a huge task and will likely question why we upgraded.

Thanks for ant help you can give me.


Top
 Profile  
 
 Post subject: Re: HQL Generating incorrect SQL for outer left joins
PostPosted: Mon Feb 14, 2011 8:59 am 
Newbie

Joined: Mon Jan 24, 2011 5:54 am
Posts: 4
The above was using a 9iDialect.

Ive now swapped to 10GDialect and this too is also wrong, and even more wrong than using 9i:

It results with:
Code:
select distinct billablepa0_.ID as ID237_, billablepa0_.VERSION as VERSION237_, billablepa0_.LINE_OF_BUSINESS_FK as LINE3_237_, billablepa0_.PROCESS_RUNNABLE_STAT_FK as PROCESS4_237_,
case when billablepa0_1_.ID is not null then 1 when billablepa0_2_.ID is not null then 2 when billablepa0_.ID is not null then 0 end as clazz_
from BILLABLE_PARTY billablepa0_
left outer join DLR_BILLABLE_PARTY billablepa0_1_ on billablepa0_.ID=billablepa0_1_.ID
left outer join SUP_BILLABLE_PARTY billablepa0_2_ on billablepa0_.ID=billablepa0_2_.ID
left outer join PROC_RUN_STATUS processrun1_ on billablepa0_.PROCESS_RUNNABLE_STAT_FK=processrun1_.ID,
PROC_RUN_STATUS processrun2_
where billablepa0_.PROCESS_RUNNABLE_STAT_FK=processrun2_.ID
and billablepa0_.LINE_OF_BUSINESS_FK=2006285483720750007
and (billablepa0_.PROCESS_RUNNABLE_STAT_FK is null or processrun2_.IGNORED=0)


Its including a inner join to PROC_RUN_STATUS processrun2_ for no reason other than to do the ignored flag clause which is not even needed and also doing an inner join to a nullable association.

Code:
select distinct billablepa0_.ID as ID237_, billablepa0_.VERSION as VERSION237_, billablepa0_.LINE_OF_BUSINESS_FK as LINE3_237_, billablepa0_.PROCESS_RUNNABLE_STAT_FK as PROCESS4_237_,
case when billablepa0_1_.ID is not null then 1 when billablepa0_2_.ID is not null then 2 when billablepa0_.ID is not null then 0 end as clazz_
from BILLABLE_PARTY billablepa0_
left outer join DLR_BILLABLE_PARTY billablepa0_1_ on billablepa0_.ID=billablepa0_1_.ID
left outer join SUP_BILLABLE_PARTY billablepa0_2_ on billablepa0_.ID=billablepa0_2_.ID
left outer join PROC_RUN_STATUS processrun1_ on billablepa0_.PROCESS_RUNNABLE_STAT_FK=processrun1_.ID,
** REMOVED LINE*** PROC_RUN_STATUS processrun2_
where
*** REMOVED LINE *** billablepa0_.PROCESS_RUNNABLE_STAT_FK=processrun2_.ID
and billablepa0_.LINE_OF_BUSINESS_FK=2006285483720750007
and (billablepa0_.PROCESS_RUNNABLE_STAT_FK is null or
**UPDATED** processrun1_.IGNORED=0)


Top
 Profile  
 
 Post subject: Re: HQL Generating incorrect SQL for outer left joins
PostPosted: Mon Feb 14, 2011 9:20 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I think your issue is that you have multiple references to 'billableParty.processRunnableStatus' in your query. Instead you should assign an alias in the join part and the use that alias in the where part. Eg.

Code:
left join billableParty.processRunnableStatus prs
where ....
and (prs is null OR prs.ignored = 0)


This was changed in Hibernate 3.5 since the old way was considered a bug. See http://opensource.atlassian.com/project ... e/HHH-4091


Top
 Profile  
 
 Post subject: Re: HQL Generating incorrect SQL for outer left joins
PostPosted: Mon Feb 14, 2011 10:55 am 
Newbie

Joined: Mon Jan 24, 2011 5:54 am
Posts: 4
Thanks! That got it!

Changed the HQL to the following:
Code:
           select distinct billableParty from com.wcg.wsf.billing.BillableParty billableParty
           left join billableParty.processRunnableStatus prs
           where billableParty.lineOfBusiness.id = :lineOfBusinessId
           and (prs is null OR prs.ignored = 0)


And the correct SQL was generated:
Code:
select distinct billablepa0_.ID as ID237_, billablepa0_.VERSION as VERSION237_, billablepa0_.LINE_OF_BUSINESS_FK as LINE3_237_, billablepa0_.PROCESS_RUNNABLE_STAT_FK as PROCESS4_237_,
case when billablepa0_1_.ID is not null then 1 when billablepa0_2_.ID is not null then 2 when billablepa0_.ID is not null then 0 end as clazz_
from BILLABLE_PARTY billablepa0_
left outer join DLR_BILLABLE_PARTY billablepa0_1_ on billablepa0_.ID=billablepa0_1_.ID
left outer join SUP_BILLABLE_PARTY billablepa0_2_ on billablepa0_.ID=billablepa0_2_.ID
left outer join PROC_RUN_STATUS processrun1_ on billablepa0_.PROCESS_RUNNABLE_STAT_FK=processrun1_.ID
where billablepa0_.LINE_OF_BUSINESS_FK=? and (processrun1_.ID is null or processrun1_.IGNORED=0)


Correct results returned.

Sadly, I fear theres quite a few queries in our app where coders have done it the old way. So an afternoon of search and replace awaits....


Top
 Profile  
 
 Post subject: Re: HQL Generating incorrect SQL for outer left joins
PostPosted: Mon Feb 14, 2011 2:01 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Great to hear that it worked.

Quote:
Sadly, I fear theres quite a few queries in our app...


Been there, done that... Good luck!


Top
 Profile  
 
 Post subject: Re: HQL Generating incorrect SQL for outer left joins
PostPosted: Fri Jul 22, 2011 10:03 am 
Newbie

Joined: Thu Jul 21, 2011 4:57 pm
Posts: 3
Can I just say that you two have helped me TREMENDOUSLY in solving a left outer join issue I was having all day yesterday. Thank you very much for posting this!! Next up is a three table join that I can't seem to code correctly for Hibernate to appreciate (I have a separate post for that one). Thanks again!!


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