I assume this is one of the gotchas of using Hibernate magic – i.e.,
attached objects – where Hibernate is trying to do it's job by persisting
changes as they happen and not necessarily waiting for a "save".

FWIW, if business logic needs to be triggered by the database side (e.g.,
from Hibernate), I'd rather have the database layer invoking/triggering
business logic within the service layer instead of pushing business logic
into the database layer.

-Burke

On Tue, Nov 22, 2011 at 2:48 PM, Darius Jazayeri <[email protected]>wrote:

> 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]
>>
>
> ------------------------------
> Click here to 
> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from 
> OpenMRS Developers' mailing list

_________________________________________

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