2009-09-03 4 views
7

Dieser ist für die Grails-Benutzer hier. Ich habe es auf der Grals-User-Mailing-Liste gefragt, aber ich dachte mir, da ich seit ein paar Tagen damit zu kämpfen habe, sollte ich so weit wie möglich ein Netz werfen.Grails - mehrfache selectsTo der gleichen Klasse mit kaskadierender Löschung

Ich habe einige Schwierigkeiten mit dem Versuch, Beziehungen zwischen zwei Objekte des gleichen Typs in einem anderen Objekt (anderer Typ) zu referenzieren die zwei Objekte.

Als ein Beispiel für das, was ich versuche zu tun, nehmen Sie Sie modellieren Beziehungen zwischen Familienmitgliedern. Jede gegebene Beziehung "gehört zu" zwei verschiedenen Familienmitgliedern. Also:

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] 
} 

Die Absicht dabei ist, dass, wenn entweder P1 oder P2 gelöscht wird, dann wird der löscht Kaskade an alle Beziehungs Objekte in der hasMany Karte. Stattdessen versuche ich jedes Mal, wenn ich es versuche, am Ende mit einer Fremdschlüsselverletzung. Ich versuchte, die „Kaskade“ Attribut wie in der Dokumentation behandelt:

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

Also dachte ich, dass ich dies auf die Person-Klasse hinzufügen würde:

static mapping = { 
    relationships cascade:'delete' 
} 

ich kein Glück hatte damit auch.

Ich schaute auch auf die devDB.script-Datei, die Grails generiert, um zu sehen, wie es die Fremdschlüssel auf Beziehung eingerichtet wurde. Wenn ich manuell "ON DELETE CASCADE" zu beiden Fremdschlüsseleinschränkungen hinzufügen, dann funktioniert es gut, aber offensichtlich manuelle Änderungen an einem automatisch generierten Datenbankskript tun ist nicht die robusteste Lösung. Im Idealfall möchte ich dieses Verhalten mit GORM angeben können.

Also was ist meine beste Wette hier? Gibt es eine Möglichkeit, kaskadierende Löschungen auf mehrere Fremdschlüssel/Eigentümer zu erzwingen? Müsste ich dies manuell mit einer onDelete Aktion auf Person tun? Muss ich in Hibernate Configs für dies, oder kann ich es in Grails/GORM irgendwie tun?

Vielen Dank für Ihre Zeit und für jede Unterstützung, die Sie anbieten können.

+0

dave, wie hast du am Ende diese Lösung? Ich denke sogar der Code von: static mappedBy = [Beziehungen: 'p1', Beziehungen: 'p2'] ist problematisch –

Antwort

1

Sie können der Person-Klasse einen beforeDelete Hook hinzufügen und das andere übergeordnete Element abfragen. Wenn der andere Elternteil nicht vorhanden ist, können Sie die Beziehung löschen. Beachten Sie, dass Sie Fremdschlüsselverstöße treffen, weil Sie wahrscheinlich beide Eltern löschen müssen, da die Beziehung eine FK für beide hat.

0

können Sie definieren auch 2 Relationshipcollections in Person

incomingRelations und outgoingRelations scheinen verwendbar Wörter (ggf. auf Ihre Domain) zu unterscheiden.

Sie könnten eine transiente Eigenschafts-Beziehungen mit einem Getter definieren nur, was die Vereinigung beider relationshipcollections zurückgibt (eine unveränderliche sicher sein, es nicht ändern/diese Änderungen würden höchstwahrscheinlich keinen Sinn machen)

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] 
} 

wenn nicht passt, würde ich versuchen, die gleichmäßige Annäherung vorgeschlagen von Miguel-Ping

Verwandte Themen