2010-11-30 46 views
1

Problème lors de la suppression des entités associées et de la persistance de cette modification dans la base de données.grails/GORM/hibernate - hasMany carte non synchronisée sur save() du parent

Avoir un objet groovy parent qui a beaucoup enfants entités qui y sont associés. Lorsque nous trouvons cet objet domaine et définissez cette liste à null, et appelez parent .save (flush: true) les éléments enfant restent dans la base de données. Je m'attendais à ce que ceux-ci aient été supprimés. Toute suggestion sera appréciée.

class Parent {

static hasMany = [child:Child] ... }

et l'enfant:

class Child {

belongsTo = [Parent] ... }

nous ajoutons l'élément et supprimer:

 
def child = new Child()

def parent = new Parent(child:child)

parent.save(flush:true) def id = parent.id //from saved entity

/// in separate transaction

parent = Parent.get(id) //id from above parent.child = null

parent.save(flush:true)

// check database - child reference still there - expect to have been deleted

Toutes les suggestions sur ce que nous avons fait ce mal serait apprécié. en utilisant des grails 1.3.5 (dernière version).

Répondre

4

La première chose, vous devez utiliser child.delete (flush: true) au lieu de null assign. Ce n'est juste pas approprié. (désolé pour l'erreur précédente)

Je vous recommande de lire la série Peter Ledbrook: http://blog.springsource.com/2010/07/02/gorm-gotchas-part-2/. Dans votre cas, la recherche « Suppression d'enfants »

Mise à jour: dans le cas où vous lisez toujours pas l'article ci-dessus (en particulier utile):

Pour supprimer un enfant, vous devez d'abord de le retirer de la collection parent, supprime-le. Mais cela provoquerait une exception de propriété non nulle puisque vous utilisez la relation belongsTo.

Solution: Vous pouvez ajouter ceci dans la classe parent:

static mapping = { 
childs cascade: "all-delete-orphan" 
} 

La carte ci-dessus contribuera à supprimer tous les enfants qui n'ont pas un parent. Ensuite, vous pouvez utiliser

parent.childs.clear() 
+1

Très bonne réponse. Lisez le blog - ça vaut le coup! – sbglasius

+0

votre solution est fondamentalement ce que j'ai dit, mais je ne l'ai pas donné. Je lui ai indiqué la documentation pertinente. Donnez à un homme un poisson, il mange un jour, enseigne à un homme à pêcher, il mange pour la vie .... – hvgotcodes

+0

Merci pour ces commentaires; Je n'ai pas réussi à faire fonctionner cela et je n'ai plus de budget pour l'enquête à ce stade.Vous avez tenté de définir la cascade "all-delete-orphelin" et aussi "all, delete-orphan". Essayez également de supprimer chaque entrée et d'appeler clear, puis d'ajouter les nouvelles lignes, mais en sauvegardant les exceptions staleObject. Si j'étudie à nouveau, je pourrais utiliser logSql de plus pour essayer de comprendre comment fonctionne Hibernate et déboguer sa configuration, mais cela devra attendre. Merci pour les réponses fournies. – Alex

0
static mapping = 
{ 
    childs cascade: "all" 
} 

cela fonctionne très bien.