views:

45

answers:

3

Entity's are classes that map directly to our database (which we use for Hibernate).

Our service classes contain business logic with these Entities before DAO is called.

We also have Command Objects, which are POJO's that relate to specific views. I've been told that the Entities themselves shouldn't be used as command objects, but the answer I was given for "why" wasn't sufficient. I'm hoping someone here can give me that answer.

Some of our views are incredibly simple. They have no more properties than the entities themselves. It seems pointless to me to map an entity to a command object which is basically a mirror image of the entity.

A: 

I don't know if this is the case for your application, but I've seen systems designed by people who never got the memo about POJOs or persistence-ignorance for entities. The entities get assigned methods that do database lookups and saves, so they have a kind of ActiveRecord thing going on, but with static methods (eewww! :-P ) instead of dynamic finders. Makes unit testing horribly difficult. The developers for those systems are extremely insistent on having a different set of objects from the entities to carry data to the jsps, because they don't want persistence logic being called on an entity in a JSP.

Oddly this isn't a big issue with Rails or Grails programmers, even though their use of ActiveRecord would seem to expose them to the same risk, they handle it by assuming the programmers are responsible adults. So there's a cultural difference at work.

It seems to me the right answer is to remove the persistence methods from the entities, it's a lot simpler than the mapping back and forth between different kinds of objects. But people get attached to their old ways of doing things and don't want to change. Again, comes down to culture and bias.

Nathan Hughes
A: 

I see no problem in re-using the domain model objects (what you are calling Entities) throughout all layers of your application - the controllers, views, service classes and DAO layer. This is a common design which you see often.

There is no problem with this if and only if you have a true separation of layers - the controllers get the model objects from the service layer, the service layer gets the model objects from the DAO layer, etc.

If you have a design where you load the Employee objects from the database by calling manager.getEmployees() from the view layer, then this will not work well.

matt b
+1  A: 

It seems that there may be some confusion in the naming of your objects. Command objects typically provide a single execute() method (with parameters) that operate on a given entity or domain object to alter it's state in accordance with the business logic. It's a very neat way of encapsulating business logic into simple objects that have very limited scope to mutate other objects.

It would seem, then, that the design you're working with actually performs some kind of bridge between Data Transfer Objects (DTOs or entities) and value objects (VOs or Command objects in your system). This can be quite wasteful since all you're doing is copying the same data into different objects.

The Data Access Object (DAO) acting on the Data Transfer Object (DTO or entity) pattern is well established and promotes good separation between layers. Typically, Hibernate will map the entities to the database, and lazily load collections within them. This is where most designs trip up because they don't allow for correct initialisation of collections because the session has gone once the thread of execution leaves the DAO. I imagine that the "Command objects" in the JSPs are actually subsets of the entities with various collections having been initialised by means of Hibernate queries.

I would suggest that you ditch the "Command objects" in favour of suitably initialised entities which would simplify your design in one respect but open you up to a potential issue in another. You will need to carefully control how collections are referenced and initialised by your JSPs. You may find yourself having to look into the Open Session In View pattern to ensure that a Hibernate Session object is available when the JSP calls the getCollection() method on some DTO that has not been initialised.

Gary Rowe