An AssertionFailure will occur when flushing a session that contains a one-to-many (or one-to-one) relationship and the many-side (or child-side) has a new, but invalid, object. This works (the invalid objects are not saved, and no errors occurs) in 1.3.6. Flushing with existing child domain objects that already have an ID, but are now invalid, do not have an issue.
Example Domain Classes:
Then run the following code:
The assertion will succeed (i.e. the book will not save), but the flush will fail with:
AssertionFailure - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) Message: null id in Book entry (don't flush the Session after an exception occurs)
It will also fail without any save, just having the new invalid book associated with the author will cause an exception on the next flush, regardless of what is causing the flush. I've been able to track it down a bit, it seems in Grails 1.3.6 the HibernateDomainClassValidator (Grails code) will set the parent object (Author) to read only which will make Hibernate 3.3 not cascade in it's AbstractFlushingEventListener.prepareEntityFlushes. This changed between Hibernate 3.3.x and 3.6.x so read only objects also cascade, though Grails 2.0.1 apparently does set invalid objects to read only anymore. What I need to discover, is how Grails is preventing a normal new invalid object from not participating in flushing, and why the behavior does not work in the one-to-many case (and possibly others).