Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am new to Hibernate so my question could be seen as a very straight forward one, also I will try not to be too generic (as I am always told off because of that), although as with all architectural question it is hard to avoid that... I never know where to ask these questions.

I have setup a webapp using Spring + Hibernate. My architecture uses a series of Controllers which make use of Services that ultimately call DAO methods to obtain my domain objects.

I also have a GenericDAO which implements all the basic data access methods (findAll, findById, save, delete, update...) which I extend for my concrete Dao so I only have to implement specific data access methods.

So a request to view all users will have this flow: the proper controller is called through request mapping, which feeds the view with the result from calling userService.getAllUsers() which at the same time makes a call to userDao.findAll().

This is all nice and I think I'm doing it properly enough.

My question relates to relationships among domain objects, so let's say users have accounts and for one view I want to show the user's details plus his list of accounts.

I never found out what's the best way to gather the accounts object list. Should I mark the relationship as Eager? Should I make a call like this:

user.accountList = accountService.findAccountsByUser(userId);

if that's the case then what's the point of specifying the relationship in the first place? Or maybe I am missing some other way here?

What happens with Many to Many relationships? Am I forced to create a domain object called UserAccount (assuming an account can be associated to several users) that maps the relations between the two?

share|improve this question
1  
It's not clear to me what purpose, if any, a "GenericDAO" serves here, as all of these methods you list (and more) are already supported by the ISession. There's a case to be made for strongly-typed repositories (testability) but isn't your "DAO" pretty much a useless wrapper around the session? ORMs replace DAOs. And it seems a lot of your concerns are essentially around the limitations imposed by this unnecessary layer in between. –  Aaronaught Jan 28 at 15:09
    
I would like to see an example of what you say working against ISession. Can you provide me with any? –  kelmer Jan 28 at 16:10
    
@Aaronaught - the main reason to wrap the Hibernate session in a repository or DAO abstraction is to avoid coupling your code to Hibernate. –  Mike Partridge Jan 28 at 21:20
    
@MikePartridge: That's not really an answer, because you haven't defined "your code". Clearly the implementation of this "DAO" is coupled to Hibernate, so some of "your code" is still coupled. Your comment presupposes that whatever references the "DAO" has some compelling reason to be decoupled from Hibernate. But does it? Like I said, repositories aren't that bad because they encapsulate aggregate roots, but his "DAO" doesn't do anything that a session doesn't also do, other than severely limiting the options available to a consumer. –  Aaronaught Jan 28 at 22:06
    
@Aaronaught: Sorry, I should have been more clear. I was referring to the idea that a business logic layer should be decoupled from the persistence layer, i.e. the dependency inversion principle. Using a DAO as an abstraction over the ORM allows you to change which you use without affecting your business logic. This may be overkill, but I don't know the OP's situation. –  Mike Partridge Jan 29 at 2:50
show 2 more comments

1 Answer

up vote 1 down vote accepted

You can also control the "eager/lazy" fetching at query time. From the docs:

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-joins

A "fetch" join allows associations or collections of values to be initialized along with their parent objects using a single select. This is particularly useful in the case of a collection. It effectively overrides the outer join and lazy declarations of the mapping file for associations and collections.

I think the more specific question you want to ask here is: how do I avoid loading too many objects (more than necessary for a given situation) but at the same time, when I do want to load them all, how do I avoid the dredded N+1 select issue

A rule of the thumb can be the following: what's the most often used fashion to get X data for my application? Do I mostly need it with its sub-entities populated or do I only seldom need those as well. This rule should guide you into setting eager/lazy fetching on the association. Then for those non-standard cases where you need data in a fashion different from the declared eager or lazy relationship-level annotation, you can override it using the above mentioned query-level fetch join.

A good way to double check all this is to debug Hibernate at the generated SQL level. For example this can quickly show you if a certain (single) Hibernate query becomes a series of (N+1) selects when getting translated to SQL. Here's a good article on how to configure this:

http://www.mkyong.com/hibernate/hibernate-display-generated-sql-to-console-show_sql-format_sql-and-use_sql_comments/

share|improve this answer
    
It's been a while since I asked this question and I'm way over my initial doubts, but your question is comprehensive enough, and summarizes what I ended up doing by following "my guts". Have an upvote, sir. –  kelmer Jan 28 at 22:20
    
your *answer is what I meant –  kelmer Jan 29 at 9:30
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.