【发布时间】:2014-01-25 17:45:04
【问题描述】:
我正在寻找一种从 JPA 实体创建数据传输对象 (DTO) 的好方法,反之亦然。 我想将 DTO 作为 JSON 发送到客户端,然后接收修改后的 DTO 并将其保存回数据库。 在将接收到的对象从 JSON 解析到其 Java 类之后,从 EntityManager 对接收到的对象执行合并方法将是最容易的。
例如有如下Entity和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 并将 DTO 复制回真实实体,以便将它们与 EntityManager 合并成为可能。
【问题讨论】:
-
为了节省一些代码行可以使用apache commons-BeanUtils库。看看这里commons.apache.org/proper/commons-beanutils/apidocs/org/apache/… 它有实用方法,可以通过反射将属性从 / 复制到 pojo
标签: java jakarta-ee jpa entitymanager dto