2013-05-01 68 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的一個嚴格限制。

相反,我添加的服務和接口庫之間的層。它保存了依賴實體(用戶)然後是挑戰。