【问题标题】:Spring Data JPA causes EntityExistsException with cascading saveSpring Data JPA 导致 EntityExistsException 与级联保存
【发布时间】:2013-05-01 21:35:03
【问题描述】:

我有一个Challenge 类,它与User 类具有多对一的关系。它是单向的,所以看起来像这样:

@Entity
@Table(name = "UserTable")
public class User {
   @Id
   private String userId;
}

@Entity
@Table(name = "ChallengeTable")
public class Challenge {
   @Id
   private String challengeId;

   @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
   @JoinColumn(name = "userId")
   private User user;
}

我正在使用Spring Data JPA,当我对CRUDRepository 对象使用CRUDRepository 中的save 方法时,如果该用户尚不存在,我希望它保留附加用户,并且如果旧用户已经存在,则将该用户合并到旧用户中。

我在UserRepository 中使用findOne(String id) 方法来获取使用userId 的用户,这就是我在Challenge 中设置的用户。

如果用户不存在,它级联就好了,但是当我尝试用预先存在的用户保存它时,我得到了异常:

javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [com.mywebsite.model.User#zk9moo78sx685g6o9yphegdx6lpoll9x]

我不确定我在这里做错了什么。将 CascadeType 更改为 ALL 不会改变任何东西。尝试完全删除 CascadeType 并首先手动保存用户也不起作用。这给了我错误:

org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: com.mywebsite.model.Challenge.user -> com.mywebsite.model.User

这似乎发生在事务退出时(因为我的服务层类用@Transactional 注释)。

如果我取出 @Transactional 注释并手动保留用户,它似乎一切正常。 (不过,我仍然想要服务级别的级联保存和事务。)

取出@Transactional 并尝试使用级联保存失败并出现SQLIntegrityConstraintViolationException 异常,因为看起来User 变成了一个分离的实体,它试图重新保留它,但主键已经存在,所以它失败。

谁能帮助我了解这里发生了什么,并帮助我在处理Spring Data JPA 中的事务时获得级联保存?

【问题讨论】:

  • 可以发一下你的服务方式吗?
  • 您是否为实体创建了 hashcode 和 equals 方法?
  • 我在两个实体上缺少哈希码和等于,但修复它并没有解决问题。
  • 服务层实际上只是做一些事情,比如设置创建和更新日期。它使用 findOne(id) 来获取旧的,并确保挑战归正确的用户所有。

标签: java spring hibernate jpa spring-data-jpa


【解决方案1】:

我尝试使用特定于休眠的级联选项,以及我能想到的所有其他选项,但我无法像 Hibernate CascadeType.SAVE_UPDATE 那样使用级联保存。我相信这是 JPA 与 Spring Data 的硬性限制。

相反,我在服务和接口存储库之间添加了一层。它保存依赖实体(用户)然后是挑战。

【讨论】:

    猜你喜欢
    • 2017-03-30
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2019-09-30
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多