Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern for JPA: Generating Data Transfer Object DTO from Entity and merging DTO to database

I am looking for a good way to create Data Transfer Objects (DTO) from a JPA Entity and vice versa. I want to send the DTO as JSON to a client, then receive the modified DTO and save it back to the database. It would be the most ease to perform the merge method from the EntityManager on the received object after it has been parsed from JSON to it's Java class. 

For example there is the following Entity and the Rest method for saving the modified object:


@Entity
@Table(name="CUSTOMER")
public class Customer {
    @Id
    Long id;
    @Version
    Long version;
    String name;
    String address;
    String login;
    String password;
    String creditCardNumber;
    @OneToMany(cascade = CascadeType.ALL)
    List<Foo> fooList;

    ... Getter() and Setter()
}

private EntityManager em;
@POST
@Path("/saveCustomer")
public void saveCustomer ( Customer  customer)   {               
   em.merge(customer);
   return;
}  

This works fine as long as I send the whole Entity Class as JSON and receive the whole Entity back. Then the EntityManager will merge the modified object to the database. But when I only want to provide a subset of the Entity (like only name and address of the customer) there will be problems:

  1. What would be the best way to create a subset of an Entity?

        -Writing the DTOs for the Entity by hand? This will generate duplicate code for every subset of the entity, which has to be maintained.

  2. How to merge a DTO which is a subset of an Entity, back to the database?

        -Using the merge() method of the EntityManager doesn't work. At first the DTO is no entity hence it can't be merged. And Just creating an Entity from the DTO, will have some unset values in the Entity. After a merge the values will be NULL in the database.


One idea I came up with, was to specify additional Entities for each subset I want to have for an entity. (Like a database view) This would be duplicate code, but it could solve the problem with the merging of the DTO to the database. (And maybe this code can be auto-generated)

For example the Entity CustomerView1 links to the same table as the Customer class, but only provides the name and address of the customer. It's a DTO for the real Customer class, which can be sent as JSON and modified outside of the server. This class can then also be merged to the database by the EntityManager.

@Entity
@Table(name="CUSTOMER")
public class CustomerView1 {
    @Id
    Long id;
    @Version
    Long version;
    String name;
    String address;
    
        ... Getter() and Setter()
}    

But I have doubts about this solution, I don't know if this will mess with the JPA's caching of Entities and may cause some problems.     


My Question is, is there a pattern to solve code duplication for DTOs and merging the DTOs back to the database?

Or is there a library for this purpose? - Something, like auto-generation for the DTOs and copying the DTOs back to the real Entity, to make it possible to merge them with the EntityManager.

like image 468
user3170740 Avatar asked Jan 07 '14 21:01

user3170740


People also ask

What is the DTO pattern?

From Wikipedia: Data transfer object (DTO), formerly known as value objects or VO, is a design pattern used to transfer data between software application subsystems. DTOs are often used in conjunction with data access objects to retrieve data from a database.

Is DTO a design pattern?

DTO stands for Data Transfer Object, which is a design pattern. It is one of the EPA patterns which we call when we need to use such objects that encapsulate and aggregate data for transfer. A DTO is similar to a data structure, but like a data structure, it doesn't contain any business logic.

What is DTO pattern in Java?

The Data Transfer Object Design Pattern is one of the enterprise application architecture patterns that calls for the use of objects that aggregate and encapsulate data for transfer. A Data Transfer Object is, essentially, like a data structure.

Can we use JPA entity as DTO?

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.


1 Answers

If the size difference between the entity and the DTO is not considerable, you can opt for sending the Entity.

When using DTOs, to overcome concurrency issues like lost update, you have to incorporate the entity version in your DTO.

If you don't use the Entity version, and the underlying row is changed between the REST GET and PUT methods, you will override changes the end-user was not really aware of.

Whenever I have to alter an Entity (Create, Update, Delete), I rely on the JPA and Hibernate Optimistic Locking mechanism.

For UI lists, tables, search results DTOs are a viable option, since you are only interested in a projection of your originating Entity. This way you speed-up retrievals and you can benefit from other SQL features (window-functions) that are not supported by JPA.

like image 182
Vlad Mihalcea Avatar answered Oct 23 '22 15:10

Vlad Mihalcea