rdk*_*rdk 81 java orm hibernate jpa
假设我有两个实体:Group和User.每个用户都可以是许多组的成员,每个组可以拥有许多用户.
@Entity
public class User {
@ManyToMany
Set<Group> groups;
//...
}
@Entity
public class Group {
@ManyToMany(mappedBy="groups")
Set<User> users;
//...
}
Run Code Online (Sandbox Code Playgroud)
现在我想删除一个组(假设它有很多成员).
问题是当我在某个Group上调用EntityManager.remove()时,JPA提供程序(在我的情况下是Hibernate)不会从连接表中删除行,并且由于外键约束而导致删除操作失败.在User上调用remove()工作正常(我猜这与拥有关系的一方有关).
那么在这种情况下如何删除组呢?
我能想到的唯一方法是加载组中的所有用户,然后为每个用户从他的组中删除当前组并更新用户.但是,为了能够删除该组,对组中的每个用户调用update()似乎很荒谬.
Grz*_*zki 79
Group
实体,因为目前User
是所有者.groups
并users
没有相互结合.我的意思是,从Group1.users中删除User1实例后,User1.groups集合不会自动更改(这对我来说非常令人惊讶),User
是主人.然后,当删除用户时,关系用户组将自动更新.但是当删除一个组时,你必须像下面这样自己删除这个关系:entityManager.remove(group)
for (User user : group.users) {
user.groups.remove(group);
}
...
// then merge() and flush()
Run Code Online (Sandbox Code Playgroud)
dam*_*ian 40
以下适用于我.将以下方法添加到不是关系所有者的实体(组)
@PreRemove
private void removeGroupsFromUsers() {
for (User u : users) {
u.getGroups().remove(this);
}
}
Run Code Online (Sandbox Code Playgroud)
请记住,要使其工作,该组必须具有更新的用户列表(不会自动完成).因此,每次将组添加到用户实体中的组列表时,还应将用户添加到组实体中的用户列表.
小智 26
我找到了一个可能的解决方案,但是......我不知道这是不是一个好的解决方案.
@Entity
public class Role extends Identifiable {
@ManyToMany(cascade ={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinTable(name="Role_Permission",
joinColumns=@JoinColumn(name="Role_id"),
inverseJoinColumns=@JoinColumn(name="Permission_id")
)
public List<Permission> getPermissions() {
return permissions;
}
public void setPermissions(List<Permission> permissions) {
this.permissions = permissions;
}
}
@Entity
public class Permission extends Identifiable {
@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinTable(name="Role_Permission",
joinColumns=@JoinColumn(name="Permission_id"),
inverseJoinColumns=@JoinColumn(name="Role_id")
)
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
Run Code Online (Sandbox Code Playgroud)
我试过这个并且它有效.如果删除角色,也关系被删除(但不是许可的实体),当你删除权限,与角色的关系被删除过(但不是角色实例).但是我们两次映射单向关系,两个实体都是关系的所有者.这会给Hibernate带来一些问题吗?哪种类型的问题?
谢谢!
上面的代码来自另一个相关的帖子.
作为JPA/Hibernate解决方案的替代方法:您可以在连接表上的foregin键的数据库定义中使用CASCADE DELETE子句,例如(Oracle语法):
CONSTRAINT fk_to_group
FOREIGN KEY (group_id)
REFERENCES group (id)
ON DELETE CASCADE
Run Code Online (Sandbox Code Playgroud)
这样,DBMS本身会在您删除组时自动删除指向该组的行.无论是从Hibernate/JPA,JDBC,在DB中手动还是以任何其他方式进行删除,它都有效.
所有主要的DBMS(Oracle,MySQL,SQL Server,PostgreSQL)都支持级联删除功能.
这对我有用:
@Transactional
public void remove(Integer groupId) {
Group group = groupRepository.findOne(groupId);
group.getUsers().removeAll(group.getUsers());
// Other business logic
groupRepository.delete(group);
}
Run Code Online (Sandbox Code Playgroud)
另外,标记方法@Transactional(org.springframework.transaction.annotation.Transactional),这将在一个会话中完成整个过程,节省一些时间。
归档时间: |
|
查看次数: |
84723 次 |
最近记录: |