wood burning stoves 2.0*
The moose likes Object Relational Mapping and the fly likes Join Fetch using EclipseLink Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Join Fetch using EclipseLink" Watch "Join Fetch using EclipseLink" New topic
Author

Join Fetch using EclipseLink

Flavio Nobili
Ranch Hand

Joined: Jan 28, 2004
Posts: 58
I'm trying to execute this code using EclipseLink but it wont work. It complains about the alias 'g'. When I use Hibernate provider it works. Does anyone know what is the problem with this code?




syntax error at [g].


Thanks.


Java Developer
SCJP, SCJD, SCWCD, SCBCD
Mike Keith
author
Ranch Hand

Joined: Jul 14, 2005
Posts: 304
Hi Flavio,

Are you sure that it works in Hibernate? It should not work. Aliasing a join fetch is specifically prohibited by the specification. If Hibernate is permitting it then they are violating the spec. If they are returning only one user even though it has multiple groups then they are violating the spec in an additional way. The spec requires that for every related group of the user you should get back a user instance, so getSingleResult should throw an exception when a user has more than one group.


-Mike
Pro JPA 2: Mastering the Java Persistence API
Arun Rao
Ranch Hand

Joined: Jan 23, 2004
Posts: 41
Mike,

You are right about the Spec. JPA specs do not allow aliasing the fetch joins. However Hibernate(thru HQL) do allow to do alias joins. I think EclipseLink followed JPA spec to the T.

Here is more on that bug (feature request)

https://bugs.eclipse.org/bugs/show_bug.cgi?id=293775
Mike Keith
author
Ranch Hand

Joined: Jul 14, 2005
Posts: 304
It's not a question of following the spec to a T. If the spec leaves something undefined, either by saying that it is undefined, or even not mentioning anything about it at all then vendors are pretty well free to do what they want. If the spec says "doing X is not allowed" then if you support doing X then you are contravening the spec and leading users down a path that no other vendors will be supporting. Users are not only locked into a proprietary feature, but one that is not even going to have an equivalent in any compliant vendor product. Unfortunately there are a number of gotchas like this in HQL that keep burning people.
Arun Rao
Ranch Hand

Joined: Jan 23, 2004
Posts: 41
Spec writers are to be blamed .. .. Just kidding.

I was going through the spec myself after I posted and I did not find anything specific related not to use the alias. If there is anything in the spec please let me know.

And I agree with you regarding vendor specific implementations of a certain spec. It can lead into serious problems when you change the 3rd party jars because of architectural decisions in a company. For eg., we moved from openJPA to Hibernate pretty recently and there were a lot of things we had to refactor to accommodate the new implementation.
Mike Keith
author
Ranch Hand

Joined: Jul 14, 2005
Posts: 304
Arun Rao wrote:Spec writers are to be blamed .. .. Just kidding.


Well, the Hibernate guys were involved in the decision making as well, so if they didn't like it they should have spoken up

I was going through the spec myself after I posted and I did not find anything specific related not to use the alias. If there is anything in the spec please let me know.

Take a look at the first para after the syntax description in 4.4.5.3.
James Sutherland
Ranch Hand

Joined: Oct 01, 2007
Posts: 553
I think the reason the spec does not allow the aliasing of join fetches, is that if you join fetch something, the same alias should not be used in the where clause, as it could result in returning corrupt objects.

i.e. in your example if the User had several groups, some of which had id=123 and another had id=456, then your join fetch query will only bring back the one with 123. This will mean the JPA provider will build and return User 'John' with only a single group 123, even though 'John' should have 2 groups, this is invalid data.

To correct this in JPA you must use a normal join in conjunction with the fetch join,

i.e.


This will return the correct result.

If you really only want the one User and one Group back, then you should just query both, without the join fetch,

i.e.


TopLink : EclipseLink : Book:Java Persistence : Blog:Java Persistence Performance
Flavio Nobili
Ranch Hand

Joined: Jan 28, 2004
Posts: 58
While it's a many-to-many relationship, it gives me a cartesian product result. I would like to get an user object populated with its groups only.
If I use this query without 'fetch' (in lazy mode), when I access the object all groups are loaded.


James Sutherland wrote:I think the reason the spec does not allow the aliasing of join fetches, is that if you join fetch something, the same alias should not be used in the where clause, as it could result in returning corrupt objects.

i.e. in your example if the User had several groups, some of which had id=123 and another had id=456, then your join fetch query will only bring back the one with 123. This will mean the JPA provider will build and return User 'John' with only a single group 123, even though 'John' should have 2 groups, this is invalid data.

To correct this in JPA you must use a normal join in conjunction with the fetch join,

i.e.


This will return the correct result.

If you really only want the one User and one Group back, then you should just query both, without the join fetch,

i.e.

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Join Fetch using EclipseLink