Solución:
- La propiedad de la relación está determinada por el lugar donde coloque el atributo ‘mappedBy’ en la anotación. La entidad que pones ‘mappedBy’ es la que NO es el propietario. No hay posibilidad de que ambas partes sean dueñas. Si no tiene un caso de uso de ‘eliminar usuario’, simplemente puede mover la propiedad al
Group
entidad, ya que actualmenteUser
es el dueño. - Por otro lado, no ha estado preguntando al respecto, pero hay una cosa que vale la pena saber. los
groups
yusers
no se combinan entre sí. Quiero decir, después de eliminar la instancia de User1 de Group1.users, las colecciones de User1.groups no se cambian automáticamente (lo cual es bastante sorprendente para mí), - Considerándolo todo, le sugiero que decida quién es el propietario. Digamos el
User
es el dueño. Luego, al eliminar un usuario, la relación usuario-grupo se actualizará automáticamente. Pero al eliminar un grupo, debes encargarte de eliminar la relación tú mismo de esta manera:
entityManager.remove(group)
for (User user : group.users) {
user.groups.remove(group);
}
...
// then merge() and flush()
Lo siguiente funciona para mí. Agregue el siguiente método a la entidad que no es propietaria de la relación (Grupo)
@PreRemove
private void removeGroupsFromUsers() {
for (User u : users) {
u.getGroups().remove(this);
}
}
Tenga en cuenta que para que esto funcione, el Grupo debe tener una lista actualizada de Usuarios (lo cual no se hace automáticamente). por lo que cada vez que agrega un Grupo a la lista de grupos en la entidad Usuario, también debe agregar un Usuario a la lista de usuarios en la entidad Grupo.
Encontré una posible solución, pero … no sé si es una buena solución.
@Entity
public class Role extends Identifiable {
@ManyToMany(cascade ={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinTable(name="Role_Permission",
[email protected](name="Role_id"),
[email protected](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",
[email protected](name="Permission_id"),
[email protected](name="Role_id")
)
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
He probado esto y funciona. Cuando elimina el rol, también se eliminan las relaciones (pero no las entidades de permiso) y cuando elimina el permiso, las relaciones con el rol también se eliminan (pero no la instancia del rol). Pero estamos mapeando una relación unidireccional dos veces y ambas entidades son las dueñas de la relación. ¿Podría esto causar algunos problemas para hibernar? ¿Qué tipo de problemas?
¡Gracias!
El código anterior es de otra publicación relacionada.