4

我有一个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方法时,如果该用户不存在,我希望它保留附加的用户,如果它已经存在,则将用户合并到旧用户中。CRUDRepositoryChallenge

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

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

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

我不确定我在这里做错了什么。更改CascadeTypetoALL不会改变任何东西。尝试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吗?

4

1 回答 1

0

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

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

于 2013-05-03T17:39:41.913 回答