Ah ha! That explains a lot of confusing things in the past with unit tests and our sessions. Seems like a bug that Context.closeSession() isn't clearing the session. I can't think of a reason not to clear it unless there is some weird timing with closing it and flushing sessions with the normal webapp.
Ben On Fri, Mar 9, 2012 at 12:23 PM, Rafal Korytkowski <[email protected]>wrote: > The problem in Mark's test is that when you call > Context.closeSession() within a transaction (our unit tests are > transactional by default) it only dettaches the session from the > transaction manager and doesn't close or even clear the session. It's > stored and attached again when you call Context.openSession(). If you > call Context.clearSession() before Context.closeSession() then it'll > work as you expect. > > Roger, Ben explained the problem with dettaching objects from > Hibernate. Our domain objects are interconnected and lazily > initialized and we would have to initialize them prior to dettaching > from Hibernate. Sometimes a graph of objects that needs to be > initialized is quite vast and it could kill performance. It would > require some redesigning of our API and our business model classes, > which is quite a big change. > > -Rafal > > On 9 March 2012 17:50, Friedman, Roger (CDC/CGH/DGHA) (CTR) > <[email protected]> wrote: > > Rafa -- > > Thanks for the spadework. > > ConceptDAO contains a wealth of not so great ideas. I think working > on REST has made us more aware of subclasses and helper classes and how to > represent them. > > Is it an option to have only the DAO layer deal with > Hibernate-connected objects, to have it serve disconnected objects on read > and reconnect them on write? Wouldn't that mean our services and the API > would no longer be engaged with the session and its cache? > > Saludos, Roger > > > > -----Original Message----- > > From: [email protected] [mailto:[email protected]] On Behalf Of Rafal > Korytkowski > > Sent: Friday, March 09, 2012 9:54 AM > > To: [email protected] > > Subject: [OPENMRS-DEV] Hibernate flush mode > > > > Hey, > > > > I have been experimenting with Hibernate flush modes recently. The > motivation was that we experienced premature flushes triggered by Hibernate > while retrieving data from the DB, which made us temporarily switch from > FlushMode.AUTO to FlushMode.COMMIT or MANUAL to execute some parts of code > like validation. > > > > The initial attempt for a more general solution was TRUNK-3069, which > switched from the AUTO to COMMIT mode for all transactions. The flush was > triggered by us around any method annotated with > @Transactional(readOnly=false), but not around > @Transactional(readOnly=true). It seemed like a good approach at first, but > then I discovered TRUNK-3103. The problem could be eventually resolved by > annotating with @Transactional dao methods, which we are considering. > > > > Anyway TRUNK-3069 disables much of Hibernate functionality to handle > flushes for us and now I think it is not how we should approach the problem. > > > > I believe we need to stay with the AUTO flush mode and tune it only when > it is needed. Unfortunately, we cannot change the flush mode in any other > place than the DAO layer where we have access to hibernate's session, > whereas most of the time we actually need to control it in the service > layer. > > > > So far whenever we needed to execute a service method in the manual > flush mode our approach was to go down to the DAO layer, which resulted in > such strange constructions as in getDefaultConceptMapType [0], where we put > in the DAO layer code that really belonged to the service layer. > > > > We have a few possibilities to deal with that. > > > > 1. We continue to handle the flush issue in DAOs the way it was before. > > 2. We have something like CustomSessionFlushTask [1]. > > 3. We have Context.getFlushMode() and Context.setFlushMode(flushMode). > > We need our own FlushMode enum so that we don't introduce a dependency > on Hibernate in the service layer. > > 4. We have @ManualFlush annotation to annotate service methods that we > want to explicitly execute in the manual flush mode. It's a more elegant > variation of 2., but slightly less useful since it requires to create a > dedicated method. For instance we have the getConcept method and if we want > it to be executed in one place only in the manual flush mode we need to > create a second method getConceptInManualFlush for the purpose of > annotating it with @ManualFlush. > > > > I am really curious what do you think or if there is anyone who has more > experience with that. > > > > [0] - > https://source.openmrs.org/browse/~br=1.9.x/OpenMRS/branches/1.9.x/api/src/main/java/org/openmrs/api/db/hibernate/HibernateConceptDAO.java?r=26243 > > [1] - > https://source.openmrs.org/browse/~br=trunk/Modules/metadatasharing/trunk/src/org/openmrs/module/metadatasharing/api/db/hibernate/CustomSessionFlushTask.java?r=26268 > > > > -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] > _________________________________________ 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]

