2011-02-08 9 views
41

Estoy usando JPA 2.0 e hibernate. Tengo una clase de usuario y una clase de grupo de la siguiente manera:JPA Hibernate de muchos a muchos en cascada

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 entonces, se crea un usuario y grupo y luego asignar el usuario al grupo.

Lo que quiero tener es cuando elimino el grupo, el grupo se eliminará (por supuesto) y todas las relaciones de grupo de usuarios que tiene el grupo se eliminarán automáticamente de la tabla de unión USER_GROUP, pero el usuario mismo no eliminado de la tabla USER.

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

Si pongo en cascada en la clase de usuario de esta manera:

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

Al eliminar el grupo, el usuario será borrado, así!

¿Hay alguna manera de lograr lo que quiero?

Respuesta

33

La forma en que lo tiene asignado, el User es el lado de la gestión de la relación, por lo tanto, será responsable de actualizar la tabla de unión.

cambiar la asignación de JoinTableUser a Group, y hacer que la propiedad de groupListUser por lo que tiene el atributo mappedBy. Eso cambiará el grupo al lado de administración de la relación y hará que las llamadas de persistencia/actualización al grupo administren la tabla de unión.

Pero tome nota de eso, no podrá simplemente agregar un grupo a un usuario, guardarlo y continuar, en su lugar tendrá que agregar un usuario al grupo y guardar el grupo para ver los cambios, pero teniendo el multidireccional de muchos a muchos con suerte, estarás administrando de cerca esa relación de todos modos.

+0

Hmmm si hago lo que dices (supongo que no hay nada en cascada puesto que no mencionas nada), cuando tengo un usuario asignado a un determinado grupo, ¿qué sucederá cuando elimine al usuario? ¿Se eliminará la relación usuario-grupo en la tabla de unión? ¿Se eliminará el grupo en sí? – Hery

+2

si lo hace de la manera que dije, la relación usuario-grupo será totalmente administrada por el lado del Grupo. Eso significa que probablemente no podrá eliminar al usuario hasta que lo haya eliminado de todos los grupos.Para que se adhiera, deberá eliminar al usuario del grupo y luego guardar el grupo. Eliminar solo al usuario no eliminará la relación del grupo de usuarios ni la tabla de unión. Sin cascada, la eliminación de un grupo eliminará las asociaciones, pero no los usuarios, que es lo que dijiste que querías en la pregunta original. – digitaljoel

+0

Ya veo ... Así que tengo que usar el grupo como el lado de la gestión ... ¿Hay alguna forma de que ambos lados sean el grupo administrativo? En otras palabras, cuando elimino un usuario, también se eliminarán el usuario y el grupo de usuarios, pero no el grupo, y cuando elimine un grupo, se eliminarán el grupo y el grupo de usuarios pero no el usuario. – Hery

4

Como ya se indicó, establezca el propietario del grupo de la relación si no necesita realizar una cascada desde el lado del usuario.

A continuación, intente utilizar cascade=CascadeType.MERGE para no eliminar en cascada al usuario cuando elimine el grupo.

5

Al ver el problema desde otro punto de vista:

Se podría añadir restricciones FK a que muchos-a-muchos tabla de asignación. En realidad, siempre debes tener FK en tu DB por razones de integridad de datos. En este caso, por ejemplo, al menos el usuario no podría eliminarse mientras deja silenciosamente filas huérfanas en la tabla de asignación.

Cuando tiene FK, puede especificar el delete cascade referential action en las restricciones, y el DB administrará la eliminación automática de la tabla de asignación, pero no de la entidad, como usted solicitó.

Cuestiones relacionadas