aspose file tools*
The moose likes Object Relational Mapping and the fly likes Hibernate:Eager fetching Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Hibernate:Eager fetching" Watch "Hibernate:Eager fetching" New topic
Author

Hibernate:Eager fetching

Hanna Habashy
Ranch Hand

Joined: Aug 20, 2003
Posts: 532
Hello all:

I am trying to eager fetch a collection of objects. My hql is:

select d.module from PermissionDefinition d left outer join fetch d.module where d.module.moduleId = 1

The above query throw the follwing error:
"query specified join fetching, but the owner of the fetched association was not present in the select list"

If I remove the "fetch" word, it works fine, and the collection of Modules is intialized and accessable outside the session scope.

Now I am confused, because the book and the manual emphasized that we should use the word "fetch" to eager fetch the objects.

Can someone explain why is the discrepancy?

In page 179 in the manual it states the following:
Join fetching - Hibernate retrieves the associated instance or collection in the same SELECT, using an OUTER JOIN.

Does that mean all join operation are eagrly fetched?

Thanks


SCJD 1.4<br />SCJP 1.4<br />-----------------------------------<br />"With regard to excellence, it is not enough to know, but we must try to have and use it.<br />" Aristotle
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Well

"select d.module from PermissionDefinition d left outer join fetch d.module where d.module.moduleId = 1 "

"SELECT d.module"

Where are you selecting "D" by itself. If you just want the module, then you don't even need a join, query on the module and not the PermissionDefinition.

I think the query might be backwards here. So the error you get is because it is looking for you to "select d". "d being the owner of the query.

Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Hanna Habashy
Ranch Hand

Joined: Aug 20, 2003
Posts: 532
Well

"select d.module from PermissionDefinition d left outer join fetch d.module where d.module.moduleId = 1 "

"SELECT d.module"

Where are you selecting "D" by itself. If you just want the module, then you don't even need a join, query on the module and not the PermissionDefinition.

I think the query might be backwards here. So the error you get is because it is looking for you to "select d". "d being the owner of the query.

Mark


The owner of this query
"select d.module from PermissionDefinition d left outer join fetch d.module where d.module.moduleId = 1" is d right?

Yes I agree that I don't need join. The above query should be:
"select d.module from PermissionDefinition d where d.module.moduleId = 1"

However in the above query the list<module> objects are lazy initialized. I want to force initialization of the list.

If I write it this way:

"select d.module from PermissionDefinition d left outer join d.module where d.module.moduleId = 1"

The query above - without the word fetch - works fine, and initialize the list. I am confused because the opposite should happen.

Also, the book suggest to use Criteria and setting the FETCH mode to join, however I prefere HQL because it is easier to understand.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

I am saying that "Select d.module " does not just have the "d" by itself, which is what Hibernate is expecting. You are not selecting just the module stuff in your query. You do not need the "module" part, that is why Hibernate is throwing an exception.

Try just

"Select d" ... in your query.

Mark
Hanna Habashy
Ranch Hand

Joined: Aug 20, 2003
Posts: 532
Try just

"Select d" ... in your query.


You are correct the above query will work, however it is not what I want to do.
DefinitionPermision has an attribute called Module, which is a forgin key to the Module table. I am trying query and return a List<Module>, instead of querying and returing a List<DefinitionPermision>
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

OK, but then you don't need that Object in the from clause.

Does that make sense. Based on your query you posted, I am thinking you want a List of PermissionDefinition objects, since that is the first Object in your from clause. If you don't need those objects at all, then you don't need to include that object in your from clause, just use your module object.

so

select m from Module m where m.moduleId = 1

That will return a list of Module objects where the id = 1.

Can you see where I got confused at what you where looking for?

Mark
Hanna Habashy
Ranch Hand

Joined: Aug 20, 2003
Posts: 532
Ok Mark, I think I wan't not clear in my original post. Consider the following scenario:

I have 2 tables PARENT and CHILD. The PARENT tabel has a foriegn key to the CHILD table. I want to query for all children of parent with ID = 1

select p.child from Parent p where p.name = 'smith'

The above query returns proxies for the children of parentId 1. How can I write the same query with the collection been intitialized?

Thanks

[ May 16, 2007: Message edited by: Hanna Habashy ]
[ May 16, 2007: Message edited by: Hanna Habashy ]
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

OK, that makes more sense.

Is your relationship bi-directional?

If so, then a query like

"Select c from Child c where c.parent.id = arent_id"

Then you just get back a list of Children.

Mark
Hanna Habashy
Ranch Hand

Joined: Aug 20, 2003
Posts: 532
Unfortuantly, the relationship is not bidirectional, that would be too easy for developers ;-)

In ORM scheme, each Parent has a child, and only one child - not a list. Child and parent together form a composite key. Hence, multiple records with the same parent exist but with different child.

I can query for parent:

select p from parent p left join fetch p.child where p.parent.id = 1

In the above query I will get a full parent object with its child initialized, however this behavior is not desirable.

I need to return a List<child> for a specific parent.
I don't understand why the following query won't work:

select p.child from Parent p left join fetch p.child where p.parent.id=1

Mark, you help is greatly appreciated.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

It doesn't work simple because

"from Parent p"

So you have to "select p", you cannot "select c".


"Unfortuantly, the relationship is not bidirectional, that would be too easy for developers ;-)"

I am not talking about the database here. I am talking about your object model. Does Child hold a reference to Parent in your object model? Developer's choose if this is there. If you do not have a reference to the Parent from a Child, then there is not a single way you will get just a List of children. Because a Child will never know what its parent's ID is.

Mark
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Hibernate:Eager fetching