History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: NH-514
Type: Improvement Improvement
Status: Open Open
Priority: Critical Critical
Assignee: Unassigned
Reporter: Dave McMullan
Votes: 36
Watchers: 27
Operations

If you were logged in you would be able to see more operations.
NHibernate

Allow expansion of the "on" clause in joins.

Created: 28/Dec/05 02:04 PM   Updated: 15/Dec/08 09:55 AM
Component/s: Core
Affects Version/s: 1.0
Fix Version/s: None


 Description  « Hide
In english, I want a list of trades in a portfolio, whether tradeprices exist or not... but if they exist, they should be dated at least 7/1/2005.

In oracle, it looks like:
from trade t, tradeprice tp where t.portfolio=53 and tp.tradeid(+)=t.tradeid and tp.effdate(+) >= '1-Jul-2005'

In ansi, it looks like:
from trade t left outer join tradeprice tp on t.tradeid=tp.tradeid and tp.effdate >= '1-Jul-2005' where t.portfolio=53

In HQL, the closest I can get is:
from trade t left join fetch t.tradeprices tp where t.portfolio=53 and tp.effdate >= '1-Jul-2005'

But that HQL generates this incorrect SQL:
from trade t left outer join tradeprice tp on t.tradeid=tp.tradeid where t.portfolio=53 and tp.effdate >= '1-Jul-2005'

This SQL is not correct because the effdate condition needs to be in the "on" clause, not the "where" clause. But the "on" clause is generated internally by NHibernate, and I haven't found a way to alter it. Is there a way?

btw... tradeprice is a lazy init bag on trade object

related forum topic: http://forum.hibernate.org/viewtopic.php?t=952606&highlight=outer+join


 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Dragos Nuta - 22/Mar/06 10:29 AM
try this:

from trade t
    left join fetch t.tradeprices tp
where t.portfolio=53
    and (tp.tradeid is null or tp.effdate >= '1-Jul-2005')

Not a solution but a workaround..

Michael Teper - 14/Aug/06 11:25 AM
This workaround is actually incorrect and will produce bad results. Specifically, if you do have a record in the tradeprices table that matches the criteria but not the tradeid, you will NOT get a null record you expect.

What is REALLY needed is implementation of the "with" keyword from Hibernate 3.0.

Luis Ferreira - 15/Nov/06 10:31 AM
Hibernate filters should also, in my opinion, add their conditions to the "on" clause.

Dragos Nuta - 10/Dec/07 02:00 AM
So should the were clauses added on collections in the mapping file when such a collection is fetch joined. The same applies to the were clauses of classes.

Charlie Helin - 23/Aug/08 08:28 AM
Just a quick question, thinking of making a own simple patch for this for the time being.

It looks like JoinFragment.AddFromFragmentString() is the place which adds the "with" statment right?

Frederik Gheysels - 31/Oct/08 04:03 AM
I would be very interested in an additional keyword in NHibernate's HQL as well. (Like the 'with' keyword that exists in Hibernate (Java version thus) HQL, like it is documented here:
http://www.hibernate.org/hib_docs/reference/en/html/queryhql-joins.html

This could be extremely usefull in combination with DTO's. :)

At the moment I work around this issue in a similar fashion like Dragos Nuta posted here, but this is indeed not always a good solution.

Michal Kowalski - 17/Nov/08 05:59 AM
This is very important issue. We can workaround most cases with complicated subqueries, but it causes serious performance issues , especially on huge tables.

Any hope to implement it in the next version ?

Tuna Toksoz - 17/Nov/08 06:04 AM
Probably it will require the AST, which is not yet planned.

Ayende Rahien - 17/Nov/08 06:09 AM
Another option is to sponsor this feature.

Michal Kowalski - 17/Nov/08 07:03 AM
I have read Nels_P_Olsen's forum post: http://forum.hibernate.org/viewtopic.php?t=961233#2375800 - cost is "currently estimated at $25k" , way too much for small firm (6 programmers) . Going for native SQL in critical cases is still cheaper. Maybe someone can have a sort of whip-around for this feature than we can spend some $ on it...

Nels P. Olsen - 17/Nov/08 12:27 PM
I am trying to get funding for this revived. It was backburnered last winter because management wanted to look into Microsoft's Entity Framework to replace our use of NHibernate. By summer they decided against that.

What about having two or three different companies sponsor this?

Tuna Toksoz - 17/Nov/08 12:40 PM
One point: The job is more than just porting AST.

Ayende Rahien - 18/Nov/08 03:52 AM
Nels,
Yes, having several companies sponsor this feature is possible.

Dave McMullan - 18/Nov/08 07:18 AM
Since I originally opened this issue 3 years ago, I've found a few workarounds... 1) use named queries with SQL having any join syntax desired... 2) use all oracle outer join syntax in HQL with no mix of ansi join syntax... 3) simply remove the extra condition in the HQL, which would return more rows than desired, then manually eliminate unwanted rows in the business logic.

Cosmin - 15/Dec/08 06:13 AM
well... what if you had to also order the result set like this.

SELECT customer.id
  from customer as c left outer join
  adddress as a on (a.customer_fk == c.id and a.add_AddressType = 1)
order by a.Street

if you remove the extra join condition then the ids would be retrieved with wrong ordering. if you wanted to elminate the unwanted row then you would have to:
- drop the extra condition (a.add_AddressType = 1)
- get also the ordering row (a.Street)
- eliminate the repeating entities by hand
- order the remaining entities by hand

this is not a problem if the set is small but what if you return 10k customers and each having several, one or no addresses. instead of only getting the small ids, the query will be at least a little less efficient, and the elimination of duplactaes and ordering will use extra cpu and ram.

does anybody have any solutin to this in HQL?!


Fabio Maulo - 15/Dec/08 09:55 AM
We are working on it
http://fabiomaulo.blogspot.com/2008/12/artorius.html

Check the grammar and passing tests and wait for the final solution.