【问题标题】:Merging Detached JPA Entities Ignoring Unmodified Fields合并分离的 JPA 实体忽略未修改的字段
【发布时间】:2015-09-16 21:32:50
【问题描述】:

短版:有没有办法告诉 JPA 在合并时忽略分离实体实例的空属性?

长版:

我有以下情况:

Web 应用程序通过 HTTP REST 与后端进行通信。后端使用 JAX-B、JAX-RS、EJB 和 JPA2.0 (EclipseLink)。应用程序功能基本上是 CRUD。

由于这种设计,通过JAX-RS接收到的所有实体都是分离的实体,导致JPA替换所有属性和关系(如果接收到的关系为null,JPA删除数据库中的关系)

这个想法是,在 A 和 B A<>---B 之间有一个 @OneToMany 单向聚合关系(这会创建一个连接表),我想修改 A 拥有的属性,保持它对 B 的引用不变。为了做到这一点,我正在做以下事情:

  1. 通过 JAX-RS 获取 A 及其所有属性和引用。
  2. 在 Web 应用程序中修改记录。
  3. 通过 JAX-RS 发送新值。
  4. 合并新的反序列化实体(处于分离状态)。

问题是,随着应用程序的增长,A 获得新的关系,传输的数据将随之增长(A 的 CRUD 操作不需要。

我知道一种解决方案是从数据库中获取未修改的记录并将其合并到代码中,但我正在寻找一种避免这种额外数据库查询的解决方案。

【问题讨论】:

  • 事先调用 find 不会影响查询的数量,除非它是一个新实体,因为 JPA 合并将查询实体以执行合并。如果已经在缓存中,则不需要查询,直接返回即可。
  • 我忘了提到缓存被禁用,在这种情况下启用它不是一个选项。
  • JPA 将在您调用 merge 时使用查询,如果它尚未在上下文的缓存中 - 它的托管实体列表。因此,如果您使用相同的 EntityManager 上下文,事先调用 em.find 不会改变查询的数量 - 您只是在 JPA 之前加载它,因此 JPA 不必这样做。您甚至可以通过收集主键列表并使用单个查询加载它们来提高效率。然后您可以自定义合并,忽略您的空值。但是 JPA 需要合并您的实体,因为它超越了那里的内容,null 和所有。

标签: java jpa jaxb jax-rs eclipselink


【解决方案1】:

如果您在 GET 请求中使用 JPA 为该实体查询 A,它应该在 L2 缓存中,因此对其使用查找操作应该会命中缓存。然后这是一个简单的案例或合并更改的值。

如果您仍想简单地合并 A 而不将合并级联到 B,您可以标记实体关系,使其在合并时不会级联。

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy = "aEntity")

【讨论】:

  • 目前我没有级联任何操作,但关系仍然会被删除,因为我正在合并一个分离的实体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-05
  • 2012-05-17
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多