我正在寻找一种好的方法,可以从JPA实体创建数据传输对象(DTO),反之亦然。我希望将DTO作为JSON发送到客户端,然后接收修改后的DTO并将其保存回数据库。在将对象从JSON解析为其Java类后,对接收的对象执行EntityManager上的merge方法将是最容易的。
例如,以下是一个实体和保存修改后对象的Rest方法:
@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;
}
只有当我将整个实体类作为JSON发送并接收整个实体时,它才能正常工作。然后EntityManager将修改的对象合并到数据库中。但是,当我只想提供实体的子集(例如仅客户的姓名和地址)时,就会出现问题:
创建实体的子集的最佳方法是什么?
-手动编写实体的DTO?这将为每个实体子集生成重复的代码,需要进行维护。
如何将作为实体子集的DTO合并回数据库?
-使用EntityManager的merge()方法无法解决问题。首先,DTO不是实体,因此无法合并。而只是从DTO创建一个实体,会在实体中保留一些未设置的值。合并后,这些值将在数据库中为NULL。
我想到的一个想法是,为我想要的每个实体子集指定其他实体。(就像数据库视图一样)这将是重复的代码,但它可以解决将DTO合并到数据库的问题。(也许可以自动生成这段代码)
例如,实体CustomerView1链接到与Customer类相同的表,但仅提供客户的姓名和地址。这是真正的Customer类的DTO,可以作为JSON发送并在服务器外部进行修改。然后,该类也可以由EntityManager合并到数据库中。
@Entity
@Table(name="CUSTOMER")
public class CustomerView1 {
@Id
Long id;
@Version
Long version;
String name;
String address;
... Getter() and Setter()
}
但我对这个解决方案有疑虑,我不知道这是否会干扰JPA实体的缓存并可能引起一些问题。
我的问题是,是否有解决DTO代码重复和将DTO合并回数据库的模式?
或者是否有为此目的而设计的库? - 类似于自动生成DTO并将它们复制回实际实体的东西,以便可以将它们与EntityManager合并。