2009-09-03 23 views
7

Este es para los usuarios de Grails aquí. Lo pregunté en la lista de correo de Grails - usuario, pero pensé que, dado que he estado luchando contra esto por un par de días, debería lanzar la red lo más amplia posible.Grails - multiple pertenece a la misma clase con eliminación en cascada

Tengo algunas dificultades para tratar de modelar las relaciones entre dos objetos del mismo tipo en otro objeto (tipo diferente) que hace referencia a los dos objetos .

Como ejemplo de lo que estoy tratando de hacer, suponga que está modelando las relaciones entre los miembros de la familia. Cualquier relación dada "pertenece a" dos miembros diferentes de la familia. Por lo tanto:

class Person { 
    hasMany[relationships: Relationship] 

    static mappedBy = [relationships:'p1', relationships:'p2'] 
} 

class Relationship { 

    Person p1 
    Person p2 
    String natureOfRelationship // for example, "cousins" 

    static belongsTo = [p1: Person, p2: Person] 
} 

La intención aquí es que si se elimina cualquiera de P1 o P2, entonces el borrado voluntad en cascada a todos los objetos de relación en el mapa hasMany. En cambio, cada vez que lo pruebo, termino con una violación de clave externa cada . He intentado utilizar el atributo "en cascada" como se explica en la documentación:

http://grails.org/doc/1.0.x/guide/single.html#5.5.2.9%20Custom%20Cascade%20Behaviour

así que pensé que iba a añadir esto a la clase Persona:

static mapping = { 
    relationships cascade:'delete' 
} 

no tenía ninguna suerte con eso tampoco.

También miré el archivo devDB.script que genera Grails, para ver cómo estaba configurando las claves externas en Relación con . Si agrego manualmente "EN ELIMINAR CASCADA" a ambas restricciones de clave externa, entonces funciona bien, pero , obviamente haciendo ediciones manuales a un script de base de datos generado automáticamente no es la solución más robusta. Idealmente, me gustaría poder especificar ese comportamiento usando GORM.

¿Cuál es mi mejor apuesta aquí? ¿Hay alguna forma de forzar eliminaciones en cascada en múltiples claves/propietarios foráneos? ¿Tendría que hacer esto manualmente con una acción onDelete en Person? ¿Necesito entrar en las configuraciones de Hibernate para esto, o puedo hacerlo en Grails/GORM de alguna manera?

Muchas gracias por su tiempo y por cualquier ayuda que pueda ofrecer.

+0

dave, ¿cómo terminaste resolviendo este? Creo que incluso el código de: static mappedBy = [relationships: 'p1', relationships: 'p2'] es problemático –

Respuesta

1

Puede agregar un gancho beforeDelete a la clase Persona y consultar al otro padre. Si el otro padre no existe, puede eliminar la relación. Tenga en cuenta que está golpeando violaciones de clave externa porque probablemente necesite eliminar ambos padres, ya que la relación tiene un FK para ambos.

0

También se pueden definir 2 Relationshipcollections en persona

incomingRelations y outgoingRelations parecen palabras utilizables para distinguir (si corresponde a su dominio).

se puede definir una relación de propiedad transitorios con solamente un captador, que devuelve la unión de ambos relationshipcollections (un inmutable para estar seguro de no modificarlo/esos cambios muy probablemente no tendrían sentido)

class Person { 
    Relationship incomingRelations 
    Relationship outgoingRelations 
    static mappedBy = [incomingRelations:'p1', outgoingRelations:'p2'] 

    static transients = ['relations'] 

    Set getRelations() { 
     //creates a new collection as union of the old ones 
     return Collections.unmodifiableSet(this.incomingRelations + this.outgoingRelations) 
    } 
} 
class Relationship { 
    static belongsTo = [p1:Person, p2:Person] 
} 

si no cabe, probaría el enfoque par sugerido por Miguel-Ping

Cuestiones relacionadas