1
在保持單向@ManyToMany關係方面存在問題。我將EclipseLink 2.3與Spring數據和MySQL一起使用。JPA:堅持重複使用的收集項目@ManyToMany
實體僞代碼:
@Entity
public class Subscriber {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
private List<SubscribersList> subscribersLists;
//...shortened...
}
@Entity
public class SubscribersList {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
//...shortened...
}
未來在一些服務創建新的列表和兩個用戶...
list = new SubscribersList("DEFAULT");
s1 = new Subscriber();
s1.getSubscribersList().add(list); //empty list is created in the constructor
repository.save(s1); //works ok
s2 = new Subscriber();
s2.getSubscribersList().add(list);
repository.save(s2); //fails with Duplicate entry '2' for key 'PRIMARY'
保存第一用戶後,列表將成爲管理的實體,但儘管這樣的保存第二個用戶JPA試圖再次創建列表:
Call: INSERT INTO SUBSCRIBERSLIST (ID, DESCRIPTION, TITLE) VALUES (?, ?, ?)
bind => [2, null, DEFAULT]
Interesti恩我的內存測試hsqldb的作品。顯然我錯過了一些東西,但不能發現問題...
'save()'將persist()和merge()與內部邏輯合併,決定使用哪一個。我對代碼做了輕微的修改:從'@ ManyToMany'中刪除了'CascadeType.PERSIST',因此需要先保存子列表列表,然後將持久訂閱者列表設置爲新創建的訂閱者,然後將訂閱者持久化。 – marek
所以在我身邊可能存在一些JPA如何工作的誤解......我想,當我創建新的對象被持久化,並將對象圖放在一些已經持久化的實體(在我的情況下是subscribersList)時,JPA足夠聰明來管理它... – marek
你不能破壞你的持久性單元中的對象。任何託管對象或新持久對象都應只引用其他託管對象。 Merge()會爲你解決問題,但會返回被管理的分離對象的副本。 – James