Spring Data JPA使用级联保存导致EntityExistsException

时间:2013-05-01 21:35:03

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

我有一个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,当我在save对象上使用CRUDRepository的{​​{1}}方法时,我希望它能够保留附加用户用户尚不存在,并将用户合并到旧用户(如果已存在)。

我在Challenge中使用findOne(String id)方法让用户使用UserRepository,这就是我在userId中设置的用户。< / p>

如果用户尚不存在,它会很好地级联,但是当我尝试使用预先存在的用户保存它时,我得到了例外:

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中使用级联保存处理交易吗?

1 个答案:

答案 0 :(得分:0)

我尝试使用特定于hibernate的级联选项,以及我能想到的其他所有内容,但我无法将级联保存工作为Hibernate CascadeType.SAVE_UPDATE应该这样做。我相信这是使用Spring Data的JPA的一个严格限制。

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