When I tried this, I started getting stack overflow exceptions. Long story short, it turns out that using
findAllByParent() causes hibernate to flush changes before executing the query. Well, guess what happens when changes are flushed? That's right - the validator gets called. Which calls
getChild(). Which calls
findAllByParent(). Which causes a flush. Which gives us infinite recursion and a stack overflow.
Once I figured out what was going on, it wasnt too hard to find the solution - tell grails/hibernate not to automatically flush changes:
parent (nullable: true, validator: { val, obj ->
if (obj.id && val) {
if (val.id == obj.id) {
return 'AFSC.cannot.be.cyclic'
}
def originalFlushMode = obj.sessionFactory.currentSession.flushMode
obj.sessionFactory.currentSession.flushMode = org.hibernate.FlushMode.MANUAL
try {
if (obj.afscService.getChild(obj, val.code)) {
return 'AFSC.cannot.be.cyclic'
}
}
catch(Exception e) {
return e.getMessage()
}
finally {
obj.sessionFactory.currentSession.flushMode = originalFlushMode
}
}
})