I have a parent object that can only be created if children are valid. . Children can only reference parent by id after it has been saved (since id is auto incremented). SO I save the parent and then assign the parent to the children to save. How do I rollback all the parent save and any child saves that have occurred if one child fails to be saved?
(This is taking place in a service layer)
parent.save(flush:true);
children.each{child->
child.parent=parent;
if(!child.save(flush:true)){
//how to roll back all previous child saves if any AND
//initial parent save also
}
}
If you throw an uncaught exception in a transactional service the transaction will rollback everything. Something like this:
package com.example
class MyService {
static transactional = true
void myMethod() {
parent.save(flush:true)
children.each{child->
child.parent = parent
if(!child.save(flush:true)){
throw new RuntimeException('Rollback')
}
}
}
}
Personally I wouldn't use a RuntimeException
in production code. I'd create my own exception and avoid filling in the stacktrace in this case. However, for example purposes the above demonstrates what you would want to do.