2009-09-03 11 views
7

Celui-ci est pour les utilisateurs Grails ici. Je l 'ai demandé sur la liste de diffusion des utilisateurs de grails, mais je me suis dit que depuis que je me bats depuis quelques jours, je devrais lancer un réseau aussi large que possible. J'ai quelques difficultés à essayer de modéliser les relations entre deux objets du même type dans un autre objet (type différent) référençant les deux objets . Pour illustrer ce que j'essaie de faire, supposons que vous modéliez les relations entre les membres de la famille. Toute relation donnée "appartient à" deux membres de la famille différents. Donc:Grails - multiple appartient à la même classe avec suppression en cascade

Le but est ici
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] 
} 

que si soit P1 ou P2 est supprimé, la suppression en cascade volonté à tous les objets relationnels dans la carte hasMany. Au lieu de cela, chaque fois que je l'essaie, je me retrouve avec une violation de clé étrangère. J'ai essayé d'utiliser l'attribut « cascade » comme dans la documentation:

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

Je pensais que je voudrais ajouter à la classe Person:

static mapping = { 
    relationships cascade:'delete' 
} 

Je n'ai pas eu la chance avec ça non plus.

J'ai également regardé le fichier devDB.script que Grails génère, pour voir comment il mettait en place les clés étrangères sur Relationship. Si j'ajoute manuellement "ON SUPPRIMER CASCADE" aux deux contraintes de clé étrangère, alors cela fonctionne bien, mais fait évidemment des modifications manuelles à un script de base de données généré automatiquement n'est pas la solution la plus robuste. Idéalement, j'aimerais pouvoir spécifier ce comportement en utilisant GORM.

Alors, quel est mon meilleur pari ici? Existe-t-il un moyen de forcer des suppressions en cascade sur plusieurs clés/propriétaires étrangers? Aurais-je besoin de le faire manuellement avec une action onDelete sur Person? Ai-je besoin d'entrer dans les configurations Hibernate pour , ou puis-je le faire dans Grails/GORM d'une manière ou d'une autre?

Merci beaucoup pour votre temps et pour toute aide que vous pouvez offrir.

+0

dave, comment avez-vous fini par résoudre celui-ci? je pense que même le code de: static mappedBy = [relations: 'p1', relations: 'p2'] est problématique –

Répondre

1

Vous pouvez ajouter un hook beforeDelete à la classe Person et interroger l'autre parent. Si l'autre parent n'existe pas, vous pouvez supprimer la relation. Notez que vous rencontrez des violations de clé étrangère parce que vous devez probablement supprimer les deux parents, puisque la relation a un FK pour les deux.

0

Vous pouvez également définir 2 Relationshipcollections en personne

incomingRelations et outgoingRelations semblent mots utilisables pour distinguer (le cas échéant à votre domaine).

Vous pouvez définir une relation de propriété transitoire avec un getter seulement, qui retourne l'union des deux relationshipcollections (un immuable pour être sûr de ne pas modifier ce/ces changements seraient plus probablement faire aucun sens)

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 ne correspond pas je voudrais essayer l'approche même suggéré par Miguel-Ping

Questions connexes