2015-12-02 69 views
0

我正在使用EclipseLink 2.6.1開發在GlassFish 4.1.1上運行的Web應用程序。我在用戶和項目之間有單向ManyToMany關係,並且當我從User.projects中移除元素併合並用戶時,連接行不會在數據庫中刪除。我做了一個小的演示應用程序將其隔離:JPA Unidirectional ManyToMany無法刪除

用戶等級:

@Entity 
@Table(name = "demouser") 
public class DemoUser implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DemoUserSeq") 
    @SequenceGenerator(name = "DemoUserSeq", sequenceName = "demouser_userid_seq", allocationSize = 1) 
    @Column(name = "userid") 
    private Integer id; 
    @Column(name = "username") 
    private String userName; 
    // some more fields 
    @JoinTable(name = "demouserprojbind", joinColumns = { 
     @JoinColumn(name = "username", referencedColumnName = "username") 
    }, inverseJoinColumns = { 
     @JoinColumn(name = "projcode", referencedColumnName = "projcode") 
    }) 
    @ManyToMany 
    private Set<DemoProject> projects; 

DemProject不具有映射多對多給用戶。綁定表「demouserprojbind」與唯一的(非空)文本列綁定,而不是連續的PK。

演示更新代碼:

DemoUser user = getUser(username); // EntityManager Query by username 
Set<DemoProject> userProjects = user.getProjects(); 
userProjects.clear(); 
EntityManager em = emf.createEntityManager(); 
utx.begin(); 
em.joinTransaction(); 
em.merge(user); 
em.flush(); 
utx.commit(); 
em.close(); 

這是一個Servlet做演示代碼 - 電動勢和UTX和注入的EntityManagerFactory和UserTransaction的。

當我跟蹤從的EclipseLink的SQL,它看起來像這樣:

DELETE FROM demouserprojbind WHERE ((projcode = ?) AND (username = ?)) 
bind => [Project2, null] 
DELETE FROM demouserprojbind WHERE ((projcode = ?) AND (username = ?)) 
bind => [Project1, null] 

這顯然是不能放在擁有實體的用戶名 - 在SQL中沒有行匹配,因而沒有行被刪除來自數據庫。

有沒有什麼我在我的保存邏輯中做錯了(我想刪除用戶和項目之間的綁定,但用戶和項目本身都應該保留)還是EcliseLink中的錯誤?

+0

這是不工作的唯一的東西,你對任何自定義映射或實體上的事件? JPA不允許在關係中使用非pk字段,雖然它受到大多數提供者支持(EclipseLink允許),但確實會導致緩存等問題,並且通常會導致警告。驗證是否未觸發某個事件來設置userName = null,或者您沒有修改只讀實例,使得該用戶名的查詢從緩存中返回已損壞的實體。 – Chris

回答

0

在你

@ManyToMany 
private Set<DemoProject> projects; 

放在anotation多對多級聯類型,像這樣:

@ManyToMany(cascade={CascadeType.MERGE, CascadeType.REMOVE }) 
private Set<DemoProject> projects; 
+0

我的演示代碼實際上有「(cascade = CascadeType.ALL)」,並且設置爲(cascade = {CascadeType.MERGE,CascadeType.REMOVE})並沒有改善這種情況。 – thomjah