2012-01-12 112 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