JPA Hibernan muchos a muchos en cascada


Estoy usando JPA 2.0 e hibernar. Tengo una clase de Usuario y una clase de Grupo de la siguiente manera:

public class User implements Serializable {
    @Id
    @Column(name="USER_ID")
    private String userId;

    @ManyToMany
    @JoinTable(name = "USER_GROUP",
               joinColumns = {
                   @JoinColumn(name = "GROUP_ID")
               },
               inverseJoinColumns = {
                   @JoinColumn(name = "USER_ID")
               }
    )
    private Set<Group> groupList;

    //get set methods
}

public class Group
{
    @Id
    @Column(name="GROUP_ID")
    private String groupId;

    @ManyToMany(mappedBy="groupList")
    private Set<User> memberList;
    //get set methods
}

Y luego, creo un usuario y un grupo y luego le asigno al usuario al grupo.

Lo que quiero es que cuando elimine el grupo, el grupo se eliminará (por supuesto) y toda la relación usuario-grupo que tenga el grupo se eliminará automáticamente de la tabla USER_GROUP join, pero el usuario en sí no se eliminará de la tabla USER.

Con el código que tengo arriba, solo la fila en la tabla de GRUPO se eliminará cuando elimine un grupo y el usuario todavía tendrá una entrada en el grupo eliminado en la tabla de unión USER_GROUP.

Si pongo cascade en la clase User así:

@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "USER_GROUP",
joinColumns =
{
    @JoinColumn(name = "GROUP_ID")
},
inverseJoinColumns =
{
    @JoinColumn(name = "USER_ID")
})
private Set<Group> groupList;

Cuando borre el grupo, el usuario será eliminado también!

¿hay alguna manera de lograr lo que quiero?

Author: Jin Kwon, 2011-02-08

3 answers

De la forma en que lo tiene mapeado, el User es el lado de administración de la relación, por lo tanto, será responsable de actualizar la tabla de combinación.

Cambie la asignación JoinTable de User a Group, y haga que la propiedad groupList de User tenga el atributo mappedBy. Eso cambiará el grupo al lado de administración de la relación y hará que las llamadas persist/update al grupo administren la tabla de unión.

Pero toma nota de eso, no podrás simplemente agregar un grupo a un usuario, guarde el usuario y continúe, en su lugar tendrá que agregar un usuario al grupo y guardar el grupo para ver los cambios, pero al tener los muchos a muchos bidireccionales, espero que esté administrando de cerca esa relación de todos modos.

 34
Author: digitaljoel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-13 22:28:10

Viendo el problema desde otro ángulo :

Puede añadir restricciones FK a su tabla de asignación muchos a muchos. En realidad, siempre debe tener FKs en su base de datos por razones de integridad de datos. En este caso, por ejemplo, al menos el usuario no se puede eliminar mientras se dejan filas huérfanas silenciosamente en la tabla de asignación.

Cuando tiene FKs, puede especificar la acción referencial on delete cascade en las restricciones, y la base de datos gestionará la eliminación automática de la asignación mesa, pero no de la entidad, como pediste.

 5
Author: Pierre Henry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-01 21:37:56

Como ya se ha indicado, haga que el grupo sea el propietario de la relación si no necesita hacer cascada desde el lado del usuario.

Luego, intente usar cascade=CascadeType.MERGE para no eliminar el usuario en cascada cuando elimine el grupo.

 4
Author: atidafi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-17 16:24:11