Let's say I have two entities: Organization and User. Every user can be a member of many organizations and every organization can have many users.
@Entity
public class User {
@ManyToMany
Set<Organization> organizations;
//...
}
@Entity
public class Organization {
@ManyToMany(mappedBy="organizations")
Set<User> users;
//...
}
Now, I want to remove an organization (let's say it has 1000 members). When the user has few organizations, this code is ok:
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);
}
But when organization count is 10,000, this solution does not have good performance.
How can I fix it?
If you have more than 50 or 100 child entities, you shouldn't map a collection.
Therefore, @OneToMany
is misleading because, in reality, @OneToFew
makes more sense. So, when many means 1000 or 10000, mapping such a collection becomes a real performance problem.
In this case, just break the @ManyToMany
association so that you map the join table UserOrganization
.
In this case, you just need the 2 @ManyToOne
associations on the join table, and, you can just issue a bulk delete query like this:
delete from UserOrganization uo
where uo.organization = :organization
That's it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With