-->
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.  [ 14 posts ] 
Author Message
 Post subject: Generic DAO question
PostPosted: Mon Oct 25, 2004 4:39 pm 
Regular
Regular

Joined: Thu Oct 07, 2004 4:45 pm
Posts: 92
I've been reading through forum posts regarding granularity of DAOs and I've decided that for my application, I'll have granular DAOs for complex queries, but I also want a generic DAO for general-purpose loading and saving of object subgraphs.

Now to my question: I want one of my generic DAO methods to load an object (by ID) and all of its children (one level deep). Is there an easy way to write this without having to interrogate the configuration metadata for the entity class? Seems like this should be very straightforward, but the reference manual, Hibernate in Action, etc. don't seem to talk about strategies for writing generic DAOs.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 4:58 pm 
Beginner
Beginner

Joined: Wed Nov 19, 2003 6:46 pm
Posts: 41
Location: Auckland, New Zealand
Why do you necessarily want "one level deep"? In my code, I have a fairly generic DAO that can load, save, saveOrUpdate, saveOrUpdateCopy, or delete a single object or a collection of objects. Works pretty well expect where it doesn't, then I write something specific :-)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 5:29 pm 
Regular
Regular

Joined: Thu Oct 07, 2004 4:45 pm
Posts: 92
cds wrote:
Why do you necessarily want "one level deep"? In my code, I have a fairly generic DAO that can load, save, saveOrUpdate, saveOrUpdateCopy, or delete a single object or a collection of objects. Works pretty well expect where it doesn't, then I write something specific :-)


Actually, I want arbitrary depth, but I figured I'd start simple.

For example, in our GUI, we have a tree structure that the user needs to be able to navigate. The entire tree can be quite large, so we only want to bring in one level of the hierarchy at a time (or maybe a couple).

So I want the UI to be able to pass the DAO the ID and class of a parent object, and the DAO should retrieve all of the children, which may be in several different collections.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 5:51 pm 
Beginner
Beginner

Joined: Wed Nov 19, 2003 6:46 pm
Posts: 41
Location: Auckland, New Zealand
rhasselbaum wrote:
Actually, I want arbitrary depth, but I figured I'd start simple.

For example, in our GUI, we have a tree structure that the user needs to be able to navigate. The entire tree can be quite large, so we only want to bring in one level of the hierarchy at a time (or maybe a couple).

So I want the UI to be able to pass the DAO the ID and class of a parent object, and the DAO should retrieve all of the children, which may be in several different collections.


Well that doesn't sound very generic. It sounds like a pretty specific requirement.

Your GUI then could call your service layer (do you have one, or does your GUI communicate directly with your DAO?) which would in turn contact the DAO to get it to ask Hibernate to load the object. If your class' mapping document defines lazy collections then you'd need to Hibernate.initialize() them before transporting them back to your GUI.

Is this making sense? I'm not really seeing your problem...


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 6:26 pm 
Regular
Regular

Joined: Thu Oct 07, 2004 4:45 pm
Posts: 92
The problem is that there are many different types of objects in the tree, and I don't want to write a method for each different object type that does basically the same thing.

The logic can be describe generically like this: For a given persistent class and ID, retrieve all of its children. I shouldn't need to couple the DAO to the particular collections found in each entity type.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 6:31 pm 
Beginner
Beginner

Joined: Wed Nov 19, 2003 6:46 pm
Posts: 41
Location: Auckland, New Zealand
rhasselbaum wrote:
The problem is that there are many different types of objects in the tree, and I don't want to write a method for each different object type that does basically the same thing.

The logic can be describe generically like this: For a given persistent class and ID, retrieve all of its children. I shouldn't need to couple the DAO to the particular collections found in each entity type.


So, when you talk about a persistent class, what do you mean by "all of its children"?

What do you need to do differently from just asking Hibernate to load an instance of a persistent class?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 6:43 pm 
Regular
Regular

Joined: Thu Oct 07, 2004 4:45 pm
Posts: 92
cds wrote:
So, when you talk about a persistent class, what do you mean by "all of its children"?


It's a tree. So I mean all of the related entities contained in collections owned by any given parent node, which is also an entity.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 6:54 pm 
Beginner
Beginner

Joined: Wed Nov 19, 2003 6:46 pm
Posts: 41
Location: Auckland, New Zealand
rhasselbaum wrote:
It's a tree. So I mean all of the related entities contained in collections owned by any given parent node, which is also an entity.


So, you have a persistent class that has a lazily loaded collection of children instances of the same type?

I would just ask Hibernate to load the instance, then initialize the collection of children. Eg:

Session s = // get the Hibernate Session
PersistentClass instance = (PersistentClass) s.load(PersistentClass.class, id);
Hibernate.initialize(instance.getChildren());


Then, when your user clicks on a child, you again ask Hibernate to load it. Will this work?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 7:04 pm 
Regular
Regular

Joined: Thu Oct 07, 2004 4:45 pm
Posts: 92
No, because each persistent class could have different sets of child collections. There is no single "getChildren" method on each persistent class.

I think I've found a way to do this using the Hibernate ClassMetadata. I was just wondering if there was an easier way. I basically want eager fetching for all of the collections owned by an entity, rather than just one.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 7:50 pm 
Beginner
Beginner

Joined: Wed Nov 19, 2003 6:46 pm
Posts: 41
Location: Auckland, New Zealand
rhasselbaum wrote:
No, because each persistent class could have different sets of child collections. There is no single "getChildren" method on each persistent class.

I think I've found a way to do this using the Hibernate ClassMetadata. I was just wondering if there was an easier way. I basically want eager fetching for all of the collections owned by an entity, rather than just one.


Well, yes, maybe you could do that, or maybe each persistent class could implement an interface that would help you out. For example, why not make each persistent class implement an interface (say) TreeEntry that defines a method:

Code:
Collection[] getChildCollections();


so that each persistent class would need to return these. Then your "generic" DAO could do something like:

Code:
Session s = // get session;
TreeEntry entry = (TreeEntry) s.load(persistentClass, id);

Collection[] colls = entry.getChildCollections;
for (int i = 0; i < colls.length; i++)
    Hibernate.initialize(colls[i]);



and that should sort it out!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 9:21 pm 
Regular
Regular

Joined: Sat Aug 28, 2004 4:15 pm
Posts: 61
I didnt really read all of this post. I skimmed....


However, it is my understanding that Hibernate only provides eager fetching for ONE association of an entity.

_________________
Joe W


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 9:32 pm 
Beginner
Beginner

Joined: Wed Nov 19, 2003 6:46 pm
Posts: 41
Location: Auckland, New Zealand
jw3525 wrote:
I didnt really read all of this post. I skimmed....


However, it is my understanding that Hibernate only provides eager fetching for ONE association of an entity.


Well true, but if you're forcing it to instantiate the other associations by calling Hibernate.initialize() on them. That's the whole point!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 26, 2004 9:21 am 
Regular
Regular

Joined: Thu Oct 07, 2004 4:45 pm
Posts: 92
Thanks for the input, but modifying the entity model is even more intrusive than creating separate DAO methods for each type.

What I really want is some kind of Hibernate.initializeAll method that initializes an object and its associations or maybe just the associated collections. I can write a method to do it using the class metadata. I was just hoping for something built-in.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 26, 2004 1:16 pm 
Beginner
Beginner

Joined: Wed Nov 19, 2003 6:46 pm
Posts: 41
Location: Auckland, New Zealand
rhasselbaum wrote:
Thanks for the input, but modifying the entity model is even more intrusive than creating separate DAO methods for each type.

What I really want is some kind of Hibernate.initializeAll method that initializes an object and its associations or maybe just the associated collections. I can write a method to do it using the class metadata. I was just hoping for something built-in.


Well OK, I'm reminded of the expression "There ain't no such thing as a free lunch"! There are obviously consequences of anything you do...

Why don't you use reflection then to find the collections on the persistent class and call initialize on them.


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