Reputation: 5053
Im looking to create a generic DAO to handle CRUD in my hibernate app. My entities have most associations as LAZY fetching. But I find in order to have hibernate be efficient as possible with the SELECTs I have to create multiple methods on my DAOs. Here's what I mean:
Entity A has two associations. Sometimes I want to retrieve this entity without loading the associations and sometimes I want it fully populated, so I'd put two methods on the DAO:
getWhatever()
getWhateverWithLoadedAssociations()
and I'd have two different queries, one without join fetch, and the other with join fetch. The result is hibernate always does a single select regardless if its LAZY or not, because I know what I want to get up front.
The problem with this is, while saving a SELECT or two, its adding complexity due to the number of methods.
So is this being to extreme? Should I just have getWhatever() and just let hibernate do another select when I need the data for the association, even though I could have saved from not doing that SELECT?
I hope this is not too confusing. I'm trying to figure out the cost of number of SELECTS due to lazy loading, vs. code complexity
thanks
Upvotes: 3
Views: 1463
Reputation: 140041
So is this being to extreme? Should I just have getWhatever() and just let hibernate do another select when I need the data for the association, even though I could have saved from not doing that SELECT?
If you have lazy associations/fetching enabled, then what is the difference if a piece of code that doesn't need the association calls getWhatever()
or getWhateverWithLoadedAssociations()
? It should result in the same number of SQL queries.
Examine the possibilities if you have just a single getWhatever()
method:
In either case, the association is only loaded when needed.
The purpose of lazy loading is so you don't have to worry about this type of thing - if the code calling the DAO method accesses the association, then it is loaded; if not, it is not.
Upvotes: 2
Reputation: 96
IMHO, I will add some following methods into the generic DAO:
findById(Id id);//lazy load
loadTree(Id id);//load full graph of the entity
load(Id id, String... includePaths);// just load some associations of the entity
Upvotes: 1
Reputation: 813
In my opinion, yes, you are being extreme.
Unless you are developing a batch procedure with thousends of these queries, there is not much difference between performing one single query and the queries that hibernate does when loading lazyly.
Anyway, if you have confirmed worries about performance in your application, it is not a bad practice what you just proposed.
Upvotes: 0
Reputation: 597362
You can have a common (in a base class) dao method:
public void initialize(Object entity);
Where you call Hibernate.initialize(entity)
;
Upvotes: 0
Reputation: 7826
I think this might qualify as premature optimization. In other words don't do it unless you know for sure there's a performance problem there.
Just let Hibernate do its lazy fetching for now, and if the app is too slow you can start adding these sort of methods only where they are needed.
Upvotes: 2
Reputation: 5370
So your problem is that you may have too many methods? I thinks it's right, because those methods do different things.
If you want to reduce the number and you're using HQL you may add a parameter to the method that says if you want to join fetch the relations:
getWhatever(WhateverFetchMode f)
where f can be a boolean, or an object that returns the HQL fragment of string that gives you that relations to fetch.
public List<MyObject> getList(boolean fetchProp1) {
return em.createQuery("select r" +
"from Object as r " +
fetchProp1 ? "left join fetch r.prop1 " : "")
.getResultList();
}
or
public List<MyObject> getList(WhateverFetchMode fetchProp1) {
return em.createQuery("select r" +
"from Object as r " +
fetchProp1.toHql()) // This returns the right join fetch
.getResultList();
}
Upvotes: 2