I've inherited a large Java app that uses Struts, Spring, and Hibernate. The classes and interfaces I deal with daily are: Struts Actions, Struts ActionForms, Value Objects, Service Interfaces and Implementations, DAO Interfaces and Implementations, and Entities. I'm pretty clear on the how and why of most of these, except I'm unsure about the correct separation of responsibilities between the ActionForms, Value Objects, and Entities. I should also mention that the Domain Model (i.e. all of the entities) doesn't contain much (if any) real business logic. This is essentially a CRUD app and most of the real logic is in the database (yuck!). Anyway, there are several distinct Java related issues that I'm wondering about:
1) It seems there is not much difference between the Entities and the Value Objects (VOs), and a lot of code must be written to transform on into the other when they pass through the service layer in either direction (Struts Actions deal only with VOs, DAOs deal only with Entities). So, VOs and Entities seem somewhat redundant. Why have them both?
2) Where should the VO<->Entity translation code go? The service layer, the Entity, the VO?
3) VOs are placed directly into ActionForms and directly bound to tags in the JSP (e.g. ). Is this a good practice? If not, what's the appropriate design?
4) It is unclear how to properly handle foreign key dependencies in the Value Objects. For example, certain VOs have a type field that, in database terms, represent a foreign key relationship into a type table. In the UI, this translates into a dropdown field that lets the user pick the type, OR a label that simply displays the textual representation of the type (depending on which screen it is). Now, should the VO have a property for the type ID, the textual representation of the type, or both? Who is responsible for translating between the two, and when?
5) The VOs have a field for their database ID. I thought VOs don't have identities? What's up with this?
I hope these questions are generic enough to be of general interest. It seems this would come up all the time in this type of architecture.
Also, I have the suspicion that this architecture is way to heavy for this app, and if you have suggestions about a better one, go ahead. But I'm mainly interested in the answer to the above questions since a different architecture is a long-term refactoring that I can't do right now.