JPA Entities and/vs DTOs

2019-03-10 23:13发布

问题:

What is the general idea to help deciding when to use DTO and when to use Entity in these cases ?

  1. UI / server side java calling the services. Should it get / send entities or DTOs ?
  2. Web service calling the services. Should the services accept entities or DTOs ?

I like reading the code that pass entities around :

  1. simpler to pass around, no need to map to DTOs
  2. dont need extra classes
  3. relations to other entities are already defined, so dont need combine related DTOs into one DTO
  4. just POJOs

But there are arguments about DTO that maps to an entity is safer, because it's a contract, and the entity can change to whatever form, and the DTO will stay the same. For example, like the entity has a field name, and the DTO also has a field name. Later on, if the requirement changes, the database table changes, the entity can change also, changing name into firstName and lastName. But the DTO will still have a field name, which is firstName + lastName.

So here's the list of the pros of using DTOs :

  1. backward compatible from the viewpoint of the code that accepts the DTOs

The cons of DTO i can think of is :

  1. have to define the DTO classes and the mapping (perhaps using dozer)
  2. the programmers would have to analyze when to use DTO and entity, i mean passing DTO for every methods is a mess
  3. overhead of conversion of entities to DTOs and vice versa
  4. I'm still unsure about the one-to-many relationship on how to map them. In JPA we can lazy initialize this, but when passing in DTO, should i initialize this or not. Shortly, DTOs cant have lazy initialized proxies, only contains values.

Please share you thoughts ..

Thank you !

Here are some quotes from different places

pro dto :

Reuse of the entity class as a DTO seems messy. The public API of the class (including annotations on public methods) no longer clearly defines the purpose of the contract it is presenting. The class will end up with methods that are only relevant when the class is being used as a DTO and some methods that will only be relevant when the class is being used as an entity. Concerns will not be cleanly separated and things will be more tightly coupled. To me that is a more important design consideration then trying to save on the number of class files created.

pro entity :

Absolutely NOT!!!

JPA entities are mapped to a database, but they are not 'tied' to a database. If the database changes, you change the mappings, not the objects. The objects stay the same. That's the whole point!

回答1:

I would go for the DTO option for the following reasons:

  • The service interface should be independant of the database, a change in one should not always require a change in the other.
  • You are making an assumption that your services will always be called by a Java client
  • Using lazy loading when the object is on the otherside of a web service call does not work well.


回答2:

Pro DTO: 1. UI most of the times require certain properties which are only for passing arguments depicting the UI state. That state is not required to be persisted hence, not required to be used on the entities.
2. Business logic should be inside entities or in helper classes for entites. You should not share that with the UI/Presentation Layer or with Client calling it.
3. Change in entities sometimes does not require a change in DTOs and vice versa.
4. Easier to perform System Level validations on DTOs in UI Services hence stopping the call to the Business Services when it should not.
5. You can implement/use other validation frameworks freely when UI side is receiving a DTO rather than entity filled with the data coming from the UI.
6. UI/Presentation layer is loosely coupled.

Here is a sample flow when DTOs are used:
UI --> MVC --> System Validations using UI Services --> Business Delegate --> Business Services --> Persist.