java - JPA : Generating Data Transfer Object DTO from Entity and merging DTO to database 的模式

标签 java jakarta-ee jpa entitymanager dto

我正在寻找一种从 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 将修改后的对象合并到数据库中。但是当我只想提供实体的一个子集时(比如只有客户的姓名和地址)就会出现问题:

  1. 创建实体子集的最佳方法是什么?

    - 手动为实体编写 DTO?这将为必须维护的实体的每个子集生成重复代码。

  2. 如何将作为实体子集的 DTO 合并回数据库?

    - 使用 EntityManager 的 merge() 方法不起作用。起初,DTO 不是实体,因此无法合并。并且只是从 DTO 创建一个实体,实体中会有一些未设置的值。合并后,数据库中的值将为 NULL。


我想出的一个想法是为实体的每个子集指定额外的实体。 (如数据库 View )这将是重复代码,但它可以解决将 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对Entities的缓存搞乱,导致一些问题。


我的问题是,是否有一种模式可以解决 DTO 的代码重复问题并将 DTO 合并回数据库?

或者是否有用于此目的的图书馆? - 一些东西,比如自动生成 DTO 并将 DTO 复制回真实实体,以便将它们与 EntityManager 合并。

最佳答案

如果实体和DTO之间的大小差异不大,您可以选择发送实体。

使用 DTO 时,要克服类似 lost update 的并发问题,您必须将实体版本合并到您的 DTO 中。

如果您不使用实体版本,并且底层行在 REST GET 和 PUT 方法之间发生更改,您将覆盖最终用户并未真正意识到的更改。

每当我必须更改实体(创建、更新、删除)时,我都会依赖 JPA and Hibernate Optimistic Locking mechanism .

对于 UI 列表、表格、搜索结果 DTO 是一个可行的选择,因为您只对原始实体的投影感兴趣。通过这种方式,您可以加快检索速度,并且可以受益于 JPA 不支持的其他 SQL 功能(窗口函数)。

关于java - JPA : Generating Data Transfer Object DTO from Entity and merging DTO to database 的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20981862/

相关文章:

java - 在 Wildfly 10 中,一个 WAR 中的类可以在同一 EAR 中另一个 WAR 的 web.xml 中引用吗?

java - 如何在 HBox 中的其他两个节点之间添加节点?

java - 我如何在 Java 中创建带有圆边的框架..我已经创建了圆边按钮

java - 其他实现策略 <sql :query>

java - Spring数据持久化列user1_.id不存在异常

java - Hibernate 中的 JPA 2.1 NamedSubgraph 忽略子类

java - 违反完整性约束

java - 警告 : There is no class model available for code generation in Visual Paradigm

java - 如何在 Java 枚举中定义静态常量?

java - TriggerBuilder<Trigger> 类型中的 withSchedule(ScheduleBuilder<SBT>) 不适用于参数 (MutableTrigger)