2012-01-12 135 views
6

我對Spring很陌生,我試圖按照我的預期做出多對多的關係。關係正常工作,創建表並正確插入數據。我期望的是,當我清空List時(即,我從「Group」類型的對象中清空ArrayList「users」),我期望系統從數據庫中刪除關係 - 但事實並非如此。Spring + JPA多對多關係

我有以下類別:

@Entity 
@Table(name = "`group`") 
public class Group 
{ 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private int id; 

    @Column(name = "name") 
    private String name; 

    @ManyToMany(cascade = {CascadeType.ALL}) 
    @JoinTable(
      name = "`user_has_group`", 
      joinColumns = @JoinColumn(name = "group_id", referencedColumnName = "id"), 
      inverseJoinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id") 
    ) 
    private List<User> users = new ArrayList<User>(); 

    ... 
} 

@Entity 
@Table(name = "`user`") 
public class User 
{ 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private int id; 

    @Column(name = "name") 
    private String name; 

    @ManyToMany(mappedBy = "users") 
    private List<Group> groups = new ArrayList<Group>(); 

    ... 
} 

下面是DAO的:

@Repository 
public class GroupJpaDao implements GroupDao 
{ 
    private EntityManager em; 

    @Transactional 
    public void save(Group group) 
    { 
     this.em.merge(group); 
    } 

    ... 

    @PersistenceContext 
    void setEntityManager(EntityManager entityManager) 
    { 
     this.em = entityManager; 
    } 
} 

@Repository 
public class UserJpaDao implements UserDao 
{ 
    private EntityManager em; 

    @Transactional 
    public void save(User user) 
    { 
     this.em.merge(user); 
    } 

    ... 

    @PersistenceContext 
    void setEntityManager(EntityManager entityManager) 
    { 
     this.em = entityManager; 
    } 
} 

下面是測試方法:

@Test 
public void test() 
{ 
    Group g = new Group(); 
    g.setName("Test group"); 
    groupDao.save(g); // Works fine - inserts the group into the database 

    User u = new User(); 
    u.setName("Test user"); 
    userDao.save(u); // Works fine - inserts the user into the database 

    g.addUser(u); 
    groupDao.save(g); // Works fine - adds the many-to-many relationship into the database 

    g.removeAllUsers(); 
    groupDao.save(g); // Doesn't work - I'm expecting it to remove all the related relationships from the database but it doesn't! 
} 

難道我做錯了什麼或者是它一些不可能做的事情?

任何提示真的很感激。

謝謝!

+0

你嘗試在你的級聯屬性中添加'delete-orphan'嗎? – fasseg 2012-01-12 17:48:57

+0

你是否聲明瞭'IdTransferringMergeEventListener'? – axtavt 2012-01-12 17:56:26

+0

不知道這是問題的原因,但保存方法不應該返回void。它應該返回合併調用的結果。嘗試執行此更改並使用返回的組:'g = groupDao.save(g);' – 2012-01-12 18:10:55

回答

2

我重讀了你的問題,現在答案很清楚。你創建一個組g,並保存它。但是由於您的保存方法使用merge,並且您沒有考慮merge返回的值將其分配給g,所以您繼續合併瞬時組g,該組從未分配任何ID。所以,每次調用合併時,實際上都會創建一個新組,而不是修改先前創建的組。

更改保存方法

public Group save(Group group) 
{ 
    return this.em.merge(group); 
} 

,結果總是重新分配給g

g = groupDao.save(g); 

當然,同樣必須爲用戶來完成。

+0

非常感謝您很多,這解決了問題! – satoshi 2012-01-14 18:13:18

0

你只是從組中刪除用戶,這還不夠。您需要從羣組中刪除所有用戶,並從所有這些用戶的羣組列表中刪除該羣組

+0

應該沒有必要,因爲擁有方是組。 – 2012-01-12 18:08:52

+0

你確定嗎?畢竟它很多。 satoshi,你可以試試這個!我必須承認我沒有先測試它:/ – davogotland 2012-01-12 18:11:06

+0

是的,我確定。該文件說:「如果該關聯是雙向的,則一方必須是所有者,一方必須是相反的結尾(即,在更新關聯表中的關係值時將忽略):」 – 2012-01-12 18:17:02