Here's a specific example of some new code we're trying to write, that is
failing.

def va = new VisitAttribute();
va.attributeType = auditDate;
va.value = DateUtils.parse("2011-11-15");
// do not set dateCreated and creator, because the framework promises to do
it

def visit = getAnExistingVisit();
visit.addAttribute(va);

*ValidationUtils.validate(visit); // <-- THIS LINE FAILS UNEXPECTEDLY*
Context.getVisitService().saveVisit(visit);


The highlighted line throws an unexpected exception (and not because
validation fails). It makes a call to the API (to get all
VisitAttributeTypes, so it can check that visit has between minOccurs and
maxOccurs of each of them), and this API call triggers a hibernate flush.
The hibernate flush tries to write visit and all its children to the DB *even
though we haven't called saveVisit yet.* And that fails because the new
attribute hasn't had dateCreated and creator set yet. (That will only
happen in the next line, because of the AOP around the saveVisit method.)

Further gory details:

   - Apparently, even though we've been setting hibernate's flush mode to
   MANUAL, Rafal has discovered that anytime we enter an @Transactional
   method, hibernate changes the flush mode to AUTOMATIC.
   - This "premature commit" has been going on forever. We haven't noticed
   it because if validation fails, and the transaction is rolled back, the
   premature commit is rolled back as well.

The two options we have in mind for approaching this are:

1. Write a custom Hibernate transaction manager, that doesn't change the
flush mode to AUTOMATIC

2. Move a bunch of logic currently in our AOP SaveHandlers into our
relatively new Hibernate interceptors.

(Rafal and I like option 2 better.)

-Darius

On Tue, Nov 22, 2011 at 11:15 AM, Rafal Korytkowski <[email protected]>wrote:

> Hi,
>
> tomorrow I want us to discuss an issue which arouse in
> https://tickets.openmrs.org/browse/TRUNK-2588 .
>
> The thing is that although we try to setup Hibernate to work in the
> MANUAL flush mode the setting has never been respected. In the effect
> we experience flushes during transactions whenever Hibernate decides
> to do so. I do not think it is bad, but it does not work with our AOP
> save handlers, because things may be saved before handlers are
> triggered resulting in not-null or transient value exceptions.
>
> I have attached a patch to the ticket which fixes this behavior by
> setting the flush mode to COMMIT at the beginning of each transaction.
> As I commented on the ticket I do not feel it is the right approach
> and we should consider changing AOP save handlers to Hibernate
> interceptors. Opinions are welcome.
>
> -Rafal
>
> _________________________________________
>
> To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to
> [email protected] with "SIGNOFF openmrs-devel-l" in the  body
> (not the subject) of your e-mail.
>
> [mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]
>

_________________________________________

To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to 
[email protected] with "SIGNOFF openmrs-devel-l" in the  body (not 
the subject) of your e-mail.

[mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]

Reply via email to