2009-09-03 6 views
7

Questo è per gli utenti Grails qui. L'ho chiesto sul graal - mailing list dell'utente, ma ho pensato che da quando ho combattuto questo per un paio di giorni dovrei lanciare una rete il più ampia possibile.Grails - multiple appartiene alla stessa classe con cancellazione a cascata

Sono in difficoltà con il tentativo di modellare le relazioni tra due oggetti dello stesso tipo in un altro oggetto (diverso tipo) che fa riferimento a due oggetti .

Come esempio di ciò che sto cercando di fare, supponiamo che si modellano le relazioni tra i membri della famiglia. Qualsiasi data relazione "appartiene a" due diversi membri della famiglia. Quindi:

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

L'intento è che se uno P1 o P2 viene eliminato, quindi la cancellazione volontà a cascata a tutti gli oggetti relazione nella mappa hasMany. Invece, ogni volta che lo provo, mi ritrovo con una violazione di chiave esterna. Ho provato ad utilizzare l'attributo "a cascata", come nella documentazione:

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

così ho pensato che vorrei aggiungere questo alla classe Persona:

static mapping = { 
    relationships cascade:'delete' 
} 

non ho avuto alcuna fortuna anche con quello.

Ho anche guardato il file devDB.script che Grails genera, per vedere come è stato impostare le chiavi esterne su Relazione. Se aggiungo manualmente "ON DELETE CASCADE" a entrambi i vincoli di chiave esterna, funziona correttamente, ma ovviamente facendo modifiche manuali a uno script di database generato automaticamente non è la soluzione più affidabile. Idealmente mi piacerebbe poter specificare il comportamento di usando GORM.

Quindi qual è la mia scommessa migliore qui? C'è un modo per forzare le eliminazioni a cascata su più chiavi esterne/proprietari? Dovrei farlo manualmente con un'azione onDelete su Person? Devo entrare nelle configurazioni di Hibernate per o posso farlo in Grails/GORM in qualche modo?

Grazie mille per il vostro tempo e per l'assistenza che potete offrire.

+0

dave, come sei riuscito a risolvere questo? penso che anche il codice di: static mappedBy = [relazioni: 'p1', relazioni: 'p2'] è problematico –

risposta

1

È possibile aggiungere un hook beforeDelete alla classe Person e interrogare l'altro genitore. Se l'altro genitore non esiste, puoi eliminare la relazione. Tieni presente che stai violando le chiavi straniere perché probabilmente dovrai eliminare entrambi i genitori, poiché la relazione ha un FK per entrambi.

0

È anche possibile definire 2 Relationshipcollections in persona

incomingRelations e outgoingRelations sembrano parole utilizzabili per distinguere (se applicabile al dominio).

è possibile definire un rapporto di proprietà transitori con solo un getter, che restituisce l'unione di entrambe le relationshipcollections (un immutabile per essere sicuri di non modificarlo/quei cambiamenti molto probabilmente alcun senso)

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

se non si adatta proverei l'approccio uniforme suggerito da Miguel-Ping