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]