2013-05-01 56 views
3

我有一个Challenge类,它具有许多与User类一对一的关系。它是单向的,所以它看起来是这样的:春数据JPA导致EntityExistsException与级联保存

@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,当我使用来自CRUDRepositorysave方法Challenge对象上,我希望它持续连接的用户如果用户不存在,并且如果用户已经存在,则将该用户合并到旧用户中。

我使用的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] 

我不知道我在这里做错了。更改CascadeTypeALL不会改变任何东西。试图完全删除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

+0

您可以发布您的服务方法? – lunr 2013-05-02 00:06:22

+0

你有哈希码和等于为实体创建的方法吗? – 2013-05-02 00:30:45

+0

我错过了哈希码,并等于两个实体,但修复并没有解决问题。 – CorayThan 2013-05-03 17:19:06

回答

0

我试过使用hibernate特有的级联选项,以及其他所有我能想到的,但我无法获得级联保存,因为休眠CascadeType.SAVE_UPDATE应该是。我相信这是Spring Data的JPA的一个严格限制。

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