1

Consider the following type of Java / Spring web application, with an SQL database:

  • there are multiple data entity types (about 100) with relations between them
  • the entities are viewed, edited or exposed to APIs, and frequently this happens with several entity types (joined)

The current approach uses three layers:

  • a data layer, that queries the tables, and uses entities that are 1:1 match to the database
  • a service layer to perform the business logic, and call the data layer as needed
  • a controller layer - exposing operations to the client side code and to the API

My questions related to handling the models are:

  1. Should every layer have its own models / entity classes? If yes, how is it best to handle copying / merging the models across the layers?
  2. Sometimes, at the service layer, an entity might require to have certain fields filled in one case, but not in other cases. Should there be two model classes for these two situations? (To make sure you can count on what fields are provided by the service)
  3. Given the large number of entities, is it worth to be consistent in addressing the issues above in the same manner, regardless of any extra complexities involved?
0
  1. I don't think each layer should have their own entity classes. Doing this would multiply number of classes and raise complexity without any real benefit. Sometimes one concept from service layer doesn't map well to relational DB (or other persistence technology) so it's sensible to create different entity classes, but mostly it's not necessary and you can have the same entity class for all layers. But keep in mind that things will change and requirements for one layer will diverge from the others (e.g. you must keep the old contract at the controller layer) - that's when you need to be prepared to create different entity classes for different use cases. If you use one entity for all layers, changes will affect all layers - e.g. renaming attribute can possibly break contract of your controllers.

  2. This is usually done for performance reasons. Best thing to do is to avoid it as much as possible - beware the dangers of premature optimizations. But sometimes this is necessary and then it's difficult to give one answer - if this is one special case where this incomplete entity is used, you might get just fine with just documenting it. If it's used more often, you should create special entity class for this, otherwise you'll get lost in following complexity.

  3. Personally I think that it's better to handle this on one-by-one basis. Entities will evolve differently and trying to handle them all in a unified way will bring a lot of overhead and useless complexity.

So, my advice is to create entity per layer only when it's necessary/meaningful. But you need to keep in mind the consequences and be ready to divide the entity class once the need arises.

Also, be careful about transactions. It's too easy to forget whether you are in a transactional context or not, especially if you're using same entity classes everywhere. From my experience, it's usually good to have clear transactional demarcation - i.e. whole service layer is transactional (by default), everything outside (controllers, tasks etc.) is not.

0
  1. They probably 'Should' however I recommend not. Map your data layer directly to your model in a Repository, use ViewModels in the controller layer, but just wrap your Models and add extra data where required instead of duplicating them.

  2. This Sounds fishy to me. Probably a sign that you need another Model

  3. It shouldn't be complicated. I recommend NOT writing your own generic mapper/orm code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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