0

Environment:

  • Java
  • Spring
  • MVC pattern
  • Hibernate

Description:

Ok, let's say I have a web application with two domain objects:

  • User
  • Report

a User can have a lot of Reports (one to many relation). Please consider that a Report is a very complex object, with a lot of attributes.

User class:

public class User { 
    private Set<Report> reports = new HashSet<Report>();
}

Report class:

public class Report {   
    //...so maaaaaaany attributes
    private String name;
}

Let's say I need to show an html page displaying a User profile with the list of associated Reports. Only reports' names appear in the list. Please comment these considerations:

  1. I don't think to eagerly load the Reports because of memory saving issues, so I'll go lazy.
  2. Even if I go lazy, the point is that I actually need the reports'name only. I don't want to load tons of information just to cherry-pick the report name!

So a possible solution is to modify the User class as follows:

public class User { 
    private Set<Report> reports = new HashSet<Report>();
    private List<String> reportNames;
}

taking the needed information from the report to the user. In my opinion, it brings two consequences:

  1. the list of report names must be kept updated
  2. i break the separation between objects domain, filling the User with information I can't easily retrieve. This approach might even be effective, but it is very ugly.

So is there a nice solution to cope with this problem? I think it is common issue for developers.

MaVVamaldo
  • 2,505
  • 7
  • 28
  • 50

1 Answers1

0

One way would be to use the following pattern:

  • Create a view object which represents exactly what you want to be displayed, let's call it UserViewObject. I would not modify the domain objects just to adapt them for the view, that would break the MVC design.

  • Implements a service method in a service class which returns a list of UserViewObject.

  • Let the service method call a DAO method in a DAO class that actually does the job.

The DAO method could make sure to only read the required data, or you could do that transformation in the service layer. It is really a bit of what you prefer, and how it fits in. But do not make the DAO layer aware of your UserViewObject.

Magnilex
  • 11,584
  • 9
  • 62
  • 84
  • maybe my question hides a more deep insight. Your approch surely makes sense, but it turns out that to efficently and flexibly manage objects, a manual intervention is required. By doing so, it seems to me that Hibernate is unsuitable for real problems because developers have to write query themselves. In other words, if Hibernate can't support developers with similar issues letting them to write queries, is it worth to use it? – MaVVamaldo Jul 04 '13 at 14:04
  • If you have a model that is truly set up to be lazy, HQL has fine support for this. This would let you fine tune which attributes to fetch from the object. Sometimes Hibernate queries the database a bit too much, but I think most of these problems can be avoided with some configuration and a well defined model. And for very complex queries, go with native SQL (JPA/Hibernate supports this too). – Magnilex Jul 04 '13 at 14:15
  • Honestly speaking, I read in every places that eagerly fetching is to be avoided like the worst thing in the world and so I manage to enable lazy loading in my web app. But I think that lazy loading is very far from being a general solution. Roughly speaking I'd say: EAGER => memory consumption :( ; minimal queries number :) LAZY => memory saving :) ; serious query number :( . So you just have to choose your poison. – MaVVamaldo Jul 04 '13 at 15:02
  • So what **is** your question? I don't really get it. Hibernate isn't magic. If you want a lazy model, you need to specify the collections which you want to fetch. This can be done with hql. But honestly, I don't really understand what you are asking. – Magnilex Jul 05 '13 at 08:40
  • I accepted your answer because it is a viable strategy for what I asked. So, I suppose you understood my originary question. But you made me think further and I suppose it confused a little the things. Just to clear it a little bit this is what I thougtht: 1) I need to load things lazily 2) I can't act as hibernate wouldn't exist (this seems trivial, but it isn't since ideally it is created to take care of persistence in a way as transparent as possible for developers) 3) if I want to push performance, I should go hql a lot and... – MaVVamaldo Jul 06 '13 at 18:04
  • ... 5) work with view (not domain) objects. As I said before, these considerations are not trivial since I feel like I can't take advantage of hibernate abstractions and, in order to do some real work (not toy tutorial application), I have go around it with hql queries and stuff. I'm not very confortable with this and I feel to break some paradigms. I just wanted to know if you think that it's ok and it is the way developers deal with hibernate normally. Ok, sorry for all this confused thoughts. – MaVVamaldo Jul 06 '13 at 18:11