Spring + JPA多对多关系
我对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!
}
难道我做错了什么或者是它一些不可能做的事情?
任何提示真的很感激。
谢谢!
我重读了你的问题,现在答案很清楚。你创建一个组g
,并保存它。但是由于您的保存方法使用merge
,并且您没有考虑merge
返回的值将其分配给g
,所以您继续合并瞬时组g,该组从未分配任何ID。所以,每次调用合并时,实际上都会创建一个新组,而不是修改先前创建的组。
更改保存方法
public Group save(Group group)
{
return this.em.merge(group);
}
,结果总是重新分配给g
:
g = groupDao.save(g);
当然,同样必须为用户来完成。
非常感谢您很多,这解决了问题! – satoshi 2012-01-14 18:13:18
你只是从组中删除用户,这还不够。您需要从群组中删除所有用户,并从所有这些用户的群组列表中删除该群组。
应该没有必要,因为拥有方是组。 – 2012-01-12 18:08:52
你确定吗?毕竟它很多。 satoshi,你可以试试这个!我必须承认我没有先测试它:/ – davogotland 2012-01-12 18:11:06
是的,我确定。该文件说:“如果该关联是双向的,则一方必须是所有者,一方必须是相反的结尾(即,在更新关联表中的关系值时将忽略):” – 2012-01-12 18:17:02
你尝试在你的级联属性中添加'delete-orphan'吗? – fasseg 2012-01-12 17:48:57
你是否声明了'IdTransferringMergeEventListener'? – axtavt 2012-01-12 17:56:26
不知道这是问题的原因,但保存方法不应该返回void。它应该返回合并调用的结果。尝试执行此更改并使用返回的组:'g = groupDao.save(g);' – 2012-01-12 18:10:55