résumé fort>
Un parent peut avoir beaucoup d'enfants. Comment écrivez-vous un service tel que, si, après avoir ajouté un parent, une erreur est une erreur lors de l'ajout d'un enfant, toute la transaction est renvoyée. Par exemple, ajoutez le parent P1, ajoutez avec succès l'enfant C1, puis lors de l'ajout d'un enfant C2 une erreur survient, P1 et C1 doivent être renvoyés. Problème détaillé strong> P> P> Le code suivant, il existe une contrainte unique sur la propriété Nom de l'enfant. Donc, si vous essayez d'ajouter le même nom deux fois avec un parent différent, l'enregistrement enfant ne doit pas être ajouté et l'enregistrement parent doit être renvoyé. P> Mon problème est que l'enregistrement parent n'est pas en train d'être renvoyé. P> J'utilise MySQL W / InnoDB avec GRAVES 1.2-M2 et Tomcat 6.018. P> Source de données strong> P> class AddRecordsService {
// boolean transactional = true //shouldn't this be all I need?
static transactional = true // this should work but still doesn't nor does it work if the line is left out completely
def addAll(params) {
println "add all"
println params
def Parent theParent = addParent(params.parentName)
def Child theChild = addChild(params.childName,theParent)
println theParent
println theChild
}
def addParent(pName) {
println "add parent: ${pName}"
def theParent = new Parent(name:pName)
theParent.save()
return theParent
}
def addChild(cName,Parent theParent) {
println "add child: ${cName}"
def theChild = new Child(name:cName,parent:theParent)
theChild.save()
return theChild
}
}
3 Réponses :
Je crois que cela devrait être:
Merci! Oui, cela est certainement censé être statique. Cependant, cela ne fonctionne toujours pas. Je pense que c'est en fait censé défaut à vrai si non spécifié. Mais enlever la ligne toutes ensemble ne fonctionne pas non plus. Peut-être que cela un bug de grails? J'ai corrigé mon code ci-dessus.
S'avère que Boolean fonctionne réellement, mais devrait être statique. Le vrai problème ne faisait pas une exception comme expliqué dans la prochaine réponse.
Vous devez également vous assurer que RunTimeException est jeté à l'intérieur du service afin que la transaction soit automatiquement roulée en arrière.
Je ferais donc ceci: p>
def addParent(pName) { println "add parent: ${pName}" def theParent = new Parent(name:pName) if(!theParent.save()){ throw new RuntimeException('unable to save parent') } return theParent } def addChild(cName,Parent theParent) { println "add child: ${cName}" def theChild = new Child(name:cName,parent:theParent) theChild.save() if(!child.save()){ throw new RuntimeException('unable to save child') } return theChild }
Merci d'avoir ajouté ces détails importants.
> Vous devez également vous assurer que RunTimeException est lancée dans le> Service afin que la transaction soit automatiquement roulées> Retour. C'était mon problème! On dirait que les greils devraient le faire par convention.
Je pense qu'il y a une option de configuration à venir version 1.2 pour faire enregistrer () lancer des exceptions au lieu de retourner null si la validation échoue
J'ai une question de suivi ici: Stackoverflow.com/questions/1640666/...
Serait .save (FildonError: vrai) accomplir cela?
@Mikey Oui, je ne serais pas sûr de ce que c'était autour de ce que j'ai répondu à cela :)
C'était ce que j'avais manqué! Transactions automatisées = échec et rouleau à l'exception, transactions manuelles = échec et retourner uniquement lorsqu'il est demandé manuellement de rouler.
Au fait, utilisez-vous le parent.WithTransaction ou votre enfant.WithTransaction, ou les deux?
@Sergeyorshanskiy Vous pouvez utiliser soit tel qu'il commencera une transaction à l'aide du même DataSource
Vous pouvez également utiliser la propriété FildonError lors de la sauvegarde de vos objets de domaine - si la sauvegarde échoue d'une erreur de validation, elle lancera une exception.
def addChild(cName,Parent theParent) { println "add child: ${cName}" def theChild = new Child(name:cName,parent:theParent) theChild.save(failOnError:true) return theChild }
Il semble que Thechild.save (FildonError: True) fonctionne, mais la définition du fichier de propriétés dans Config.Groovy ne le fait pas. BTW - J'ai une question de suivi ici: Stackoverflow.com/Questtions/1640666/...