Hello,
Recently We've ran into a well-known "collection [...] was not processed by flush()" issue with default Hibernate Validator event listener (org.hibernate.cfg.beanvalidation.BeanValidationEventListener) and validator (org.hibernate.validator.engine.ValidatorImpl) implementations.
See following related posts for more details on the issue itself and why it appears:
http://opensource.atlassian.com/project ... wse/HV-246 http://opensource.atlassian.com/project ... e/HHH-2763 (Just for the record, our environment is Hibernate 3.5.3-Final, Spring 3.0.3.RELEASE, Hibernate Validator 4.1.0.Final)
Having debugged the application with Validator sources attached and hibernate.show_sql=true I've managed to track down the place where validator has been referencing lazily-initialized objects.
It turned out that method org.hibernate.validator.engine.resolver.SingleThreadCachedTraversableResolver.buildHashCode(); uses traversed object's hashCode() method, making assumption that hashCode does not depend on lazily-initialized fields.
Code:
public int buildHashCode() {
int result = traversableObject != null ? traversableObject.hashCode() : 0; // here's the "assumption" place
...
return result;
}
And of-course our problem was that child object used lazily-initialized parent to build its hash-code. This was done because in most cases we do not use parent object && hash code. And when we use hash code the parent object is always loaded. Well, until now :)
The question is the following: is it the problem in our design which should be changed to eagerly fetch the parent object (if yes then why) or it's a use-case overlook in HV we should try out some workarounds like they suggest in the tickets mentioned above (E.g. extend the BeanValidationEventListener and having access to current session, clear the collection of unprocessed objects which additionally appeared after the validation took place)?
Regards,
Roman