如何从 @ManyToMany 关系中删除与 JPA 和 Hibernate 中的许多子对象的子对象
Posted
技术标签:
【中文标题】如何从 @ManyToMany 关系中删除与 JPA 和 Hibernate 中的许多子对象的子对象【英文标题】:How to remove child objects from a @ManyToMany relation with lots of children in JPA and Hibernate 【发布时间】:2017-10-19 17:32:49 【问题描述】:假设我有两个实体:组织和用户。每个用户都可以是多个组织的成员,每个组织都可以有多个用户。
@Entity
public class User
@ManyToMany
Set<Organization> organizations;
//...
@Entity
public class Organization
@ManyToMany(mappedBy="organizations")
Set<User> users;
//...
现在,我想删除一个组织(假设它有 1000 个成员)。 当用户的组织很少时,这段代码就可以了:
void removeOrgFromUser(Integer userId,Integer orgId)
User user = session.load(User.class, userId);
for (Organization org : user.organizations)
if(org.getId().equals(orgId))
user.organizations.remove(org);
session.update(user);
但当组织数为 10,000 时,此解决方案的性能不佳。
我该如何解决?
【问题讨论】:
从连接表中删除行。 我想用 hibernate 或 hql 做到这一点, @Antoniossss 使用 sql native? 是的,使用带有 user_id 和 departament_id 标准的准备好的语句 从这里尝试 JBNizet 的答案:***.com/questions/8699153/… 在删除组织之前清除组织中的用户集合。另一种方法是按照@Antoniossss 的建议通过 SQL。 【参考方案1】:如果您有超过 50 或 100 个子实体,则不应映射集合。
因此,@OneToMany
具有误导性,因为实际上@OneToFew
更有意义。因此,当 many 表示 1000 或 10000 时,映射这样的集合就成了一个真正的性能问题。
在这种情况下,只需断开 @ManyToMany
关联,以便映射连接表 UserOrganization
。
在这种情况下,您只需要连接表上的 2 个 @ManyToOne
关联,并且您可以像这样发出批量删除查询:
delete from UserOrganization uo
where uo.organization = :organization
就是这样!
【讨论】:
以上是关于如何从 @ManyToMany 关系中删除与 JPA 和 Hibernate 中的许多子对象的子对象的主要内容,如果未能解决你的问题,请参考以下文章