Imagine relationships:
User has many Permissions
Permission has many Users
We can create a N para N
relationship as follows:
User.class
public class User {
/*Many attributes here*/
private List permissions;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "users")
public List getPermissions() {
return permissions;
}
public void setPermissions(List permissions){
this.permissions = permissions;
}
}
Permission.class
public class Permission{
/*Many attributes here..*/
private List users;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
So you can affirm a N pra N
relationship, where owner is the Permission
class.
When I want to say that user 1 has the permissions 3 and 5 , for example, I do something like this:
User u = (User)session.get(User.class, 1);
List permissions = new ArrayList<>();
permissions.add(new Permission(3));
permissions.add(new Permission(5));
for(Object permission : permissions){
Permission p =
(Permission) session.get(Permission.class, ((Permission)permission).getId());
p.getUsers().add(u);
}
session.getTransaction().commit();
Everything working correctly.
However, when I view the logs , I see that hibernate is firstly deleting all records in the associative table permission_user
related to that permission, then adding it all up again. (Since we have access to all previously associated users when we call p.getUsers(); //pega todos os usuários já associados
)
Let's assume that 3 permission already has the 100 user and the 101 user associated with it, and so I want to now associate the user 1 . In the logs , hibernate is running more or less this ...
delete from permission_user where id_permission = ? //deve ser id 3
insert into permission_user (id_permission, id_user) values (?, ?) //deve ser 3 e 100 respectivamente
insert into permission_user (id_permission, id_user) values (?, ?) //deve ser 3 e 101 respectivamente
insert into permission_user (id_permission, id_user) values (?, ?) //deve ser 3 e 1 respectivamente
The issue is, since I am associating a new user, my expectation is that hibernate can only execute insert
(Since user 100 and 101 are already present in the associative table).
And this occurs for each permission. So, if I say that user 1 will have the permissions, 3 , 5 , 10 11 , 12 , 13 , 15 , 16 and 19 and each of these permissions already has users associated with it, about 10 users for example, hibernate will execute more than 100 instructions to perform what I want. This is really very problematic.
Could someone give me a light?
Thank you in advance.