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]

