I *believe* all that we want to move from the service layer to the DAO
layer is the assignment of creator and dateCreated. And that sounds
appropriate for the database layer.

It's something we were already planning to do at some point, and I'm pretty
sure it will solve our current issue. Let's discuss tomorrow.

-Darius

On Tue, Nov 22, 2011 at 6:10 PM, Burke Mamlin <[email protected]>wrote:

> 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
>
>
> ------------------------------
> 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