【问题标题】:How to avoid persisting new object when oneToMany connection?oneToMany连接时如何避免持久化新对象?
【发布时间】:2015-07-19 01:07:09
【问题描述】:

returnreason-table 中有三行,我不希望那里有更多行。用户只需选择三个原因之一,我只想要 rma-table 的 id。现在每次插入新的 rma 时都会在原因表中插入一个新行。我可以取消表之间的关系,但我想知道是否有更好的解决方案来避免在持久化 rma 对象时插入新行?如果我从 Rma 类中删除 cascadeType,它就没有帮助/工作。然后我收到一条错误消息,说 jpa 找到了一个没有持久化的对象或类似的东西。

如果我关闭了 cascadetype.ALL 则会出现错误消息

java.lang.IllegalStateException:在同步期间,通过未标记为级联 PERSIST 的关系找到了一个新对象:com.entity.Returnreason[ returnreasonId=null ]。

public class Rma implements Serializable {
@ManyToOne(cascade = CascadeType.ALL)
private Returnreason returnreasonReturnreasonId;

public class Returnreason implements Serializable {
@OneToMany(mappedBy = "returnreasonReturnreasonId", cascade = CascadeType.ALL)
private Collection<Rma> rmaCollection;

【问题讨论】:

  • “然后我收到一条错误消息,表示 jpa 找到了一个对象,该对象没有被持久化或类似的东西。”您能否向我们提供有关该错误的更多信息?
  • @over9k - 我在我的问题中添加了一条错误消息。

标签: java mysql jpa eclipselink one-to-many


【解决方案1】:

JPA 方法要求模型使用托管实体,而您似乎正在尝试将托管实体与上下文之外的事物相关联。这是一种不好的做法,并且 JPA 需要抛出异常,因为它无法告诉您打算如何处理非托管实例。

你有两个选择

  1. 读入您的 3 Returnreason 并使用这些实体进行合并。 如果真的只有 3 个,您可以更改缓存选项 所以它们总是在缓存中,以便进行 em.find 操作 不必打数据库。
  2. 删除 Rma 类到 Returnreason 类的映射,然后 将 returnreasonReturnreasonId 字段映射为基本映射。你 然后可以直接在Rma实体中设置值

第一个选项可能是最常用的,并且确实是必需的,因为您应该在每次添加新的 Rma 实例时一直维护 Returnreason rmaCollection。虽然看起来您只需要设置 Rma.returnreasonReturnreasonId,但这些是 java 对象,您的应用程序负责维护双向关系的双方。

【讨论】:

  • 基本上我已经阅读了那些 returnreasons,当我创建一个选项/下拉列表时(
  • 如果您已经在某个时候读过它们,那么使用 em.find(id, Returnreason.class) 将为您提供托管实例,以便在将它们添加到 Rma 引用时使用。如果您最终将对象传递给/从客户端传递,我会说只需在 Rma 实例上调用 merge,因为 JPA 将为您处理所有事情。但除非您已完全填充 Returnreason 实例,否则使用任何未设置的字段调用合并将导致数据库中的数据被空值覆盖。
猜你喜欢
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多