It doesn't look ok to me ;-) Again in ProcessFile you're trying to read
something that wasn't yet committed. The easiest way to check (but NOT a
solution) is to add Thread.sleep(10000) in the first line of
ProcessFile.run() so that TriggerPatientAfterAdvice has enough time to
complete as well as any other advice around that service method and a
transaction is committed before ProcessFile starts doing anything.

The easiest way to fix it is to store properly initialized PatientState
(not just an id) in some ProcessFile field.

In your case you could also try to change the transaction isolation level
to READ_UNCOMMITTED. You just need to annotate the getPatientState method
with @Transactional(isolation = Isolation.READ_UNCOMMITTED). Note that you
should not use such  a method in other places in your code thus you may
consider creating a new one just for use in ProcessFile. This solution may
fail as your PatientState may be locked for read and write by the other
transaction.

Also you're using Context.openSession() and Context.authenticate(). There's
an alternative [0].

@Mark, I don't think we've got such a wiki, but all what is mentioned in
Spring docs [1] is applicable for OpenMRS.

-Rafal

[0] -
http://svn.openmrs.org/openmrs-modules/validation/trunk/api/src/main/java/org/openmrs/module/validation/ValidationThread.java

[1] -
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/transaction.html


On 25 January 2012 19:45, Ben Wolfe <[email protected]> wrote:

> Hmm, looks ok to me. :-(  Can you log right before the service call to
> make sure the id is valid?  Perhaps the property on the runnable is not
> staying as you think it is?  Or its being overwritten again by the next
> call?
>
> Ben
>
>
> On Wed, Jan 25, 2012 at 12:09 PM, McKee, Steven Jay <[email protected]>wrote:
>
>>  Here’s the class flushing the session and creating the second thread at 
>> lines 115-116:****
>>
>>
>> http://svn.openmrs.org/openmrs-modules/chica/branches/chica%201.7.x%20compatible/src/org/openmrs/module/chica/advice/TriggerPatientAfterAdvice.java
>> ****
>>
>> ** **
>>
>> ** **
>>
>> I receive a null pointer exception intermittently in the following class
>> at line 78 due to the PatientState object coming back null:****
>>
>>
>> http://svn.openmrs.org/openmrs-modules/chica/branches/chica%201.7.x%20compatible/src/org/openmrs/module/chica/advice/ProcessFile.java
>> ****
>>
>> ** **
>>
>> I have also verified we have the correct (and not null) patient ID
>> because we have a logging process that logs the ID before the execution of
>> the ProcessFile class.****
>>
>> ** **
>>
>> Steve****
>>
>> ** **
>>
>> ** **
>>
>> ** **
>>
>> *From:* [email protected] [mailto:[email protected]] *On Behalf Of *Ben Wolfe
>> *Sent:* Wednesday, January 25, 2012 11:36 AM
>>
>> *To:* [email protected]
>> *Subject:* Re: [OPENMRS-DEV] Hibernate Sessions Issue****
>>
>> ** **
>>
>> Having transactions around an entire unit of work is important.  If one
>> thing fails it is nice to have all changes rolled back.
>>
>> Hibernate is supposed to keep track of things that are changed within a
>> transaction so that it seems like they are flushed (or it flushes them
>> before reads).
>>
>> Can you give a link to some code?  Or can you post some for us to see?
>>
>> Ben****
>>
>>  On Wed, Jan 25, 2012 at 11:14 AM, Dugan, Tammy Marie <[email protected]>
>> wrote:****
>>
>> I think the issue isn't threading so much as it is a nested transaction
>> issue. I am pretty sure that nested transactions are not committed.
>> Therefore I think Steve's problem is that the outermost transaction is not
>> finished and hasn't finished when the thread is created. There is no easy
>> way around this because so many service methods in openmrs are
>> transactional. That is why I have argued against transactional annotations
>> on service methods. The only way I could ever get around this was using a
>> hack with stateless sessions.
>>
>> Tammy Dugan
>> Quoting Wyclif Luyima <[email protected]>:****
>>
>> @McKee, this is why i said i'm not sure if the way you are coding up the
>> threads is correct, starting thread A and call flushSession() on it and
>> then starting thread B afterwards doesn't guarantee that all lines of code
>> in thread B will executed after all lines in thread A unless you have
>> explicitly called threadA.join() in thread B.
>>
>> Wyclif.
>>
>> On Wed, Jan 25, 2012 at 8:12 AM, McKee, Steven Jay <[email protected]
>> >wrote:****
>>
>>  I?m calling flush session before the second thread is even created.  Is*
>> ***
>>
>>
>> the flush session call on a thread of its own?  Why else would the data
>> not
>> be there if I explicitly tell it to flush?  How would you go about making
>> ****
>>
>> the second thread wait on the first to successfully flush?****
>>
>> ** **
>>
>> Thanks,****
>>
>> Steve****
>>
>> ** **
>>
>> *From:* [email protected] [mailto:[email protected]] *On Behalf Of *Wyclif
>> Luyima
>> *Sent:* Tuesday, January 24, 2012 10:16 PM
>> *To:* [email protected]
>> *Subject:* Re: [OPENMRS-DEV] Hibernate Sessions Issue****
>>
>> ** ******
>>
>>
>>
>> I'm not sure how you are coding this out, but of course what i said can
>> fail if the second thread tries to accesses the created  patientState
>> before the first has actually flushed its session . Basically ensure, you
>> can make the second thread wait on the first to guarantee that the session
>> ****
>>
>> is flushed.****
>>
>> ** **
>>
>> Wyclif********
>>
>>
>>
>> On Tue, Jan 24, 2012 at 9:26 PM, McKee, Steven Jay <[email protected]>***
>> *
>>
>> wrote:********
>>
>>
>>
>> I was able to give flushing session one a try, but it did not solve the**
>> **
>>
>> problem.  I?m still running into conditions where the spawned thread****
>>
>>
>> intermittently does not know about the PatientState object created in****
>>
>> session one.****
>>
>>  ****
>>
>> Steve****
>>
>>  ****
>>
>> *From:* McKee, Steven Jay
>> *Sent:* Friday, December 30, 2011 10:24 AM
>> *To:* '[email protected]'
>> *Subject:* RE: [OPENMRS-DEV] Hibernate Sessions Issue****
>>
>>  ****
>>
>> Thanks, Wyclif!  I?ll give this a try.****
>>
>>  ****
>>
>> Steve****
>>
>>  ****
>>
>> *From:* [email protected] [mailto:[email protected]] *On Behalf Of *Wyclif
>> Luyima
>> *Sent:* Thursday, December 29, 2011 4:45 PM
>> *To:* [email protected]
>> *Subject:* Re: [OPENMRS-DEV] Hibernate Sessions Issue****
>>
>>  ********
>>
>>
>>
>> The hibernate session is associated to the same thread as that of the
>> authenticated user's context, so if any updates/inserts  in one  thread
>> are
>> not yet persisted to the DB until the session is flushed, implying the
>> changes won't be visible to other threads. You need to ensure that the
>> first session is flushed, you can manually call Context.flushSession() on
>> ****
>>
>> the first thread before starting the second thread.****
>>
>>  ****
>>
>> Wyclif********
>>
>>
>>
>> On Thu, Dec 29, 2011 at 3:56 PM, Burke Mamlin <[email protected]>**
>> **
>>
>> wrote:********
>>
>>
>>
>> Are you creating the PatientState within an application session in the
>> first session ? calling openSession & closeSession on either end?  When
>> you
>> saw then session one "inserts a new PatientSate", that means that you are
>> ****
>>
>> creating the new object through the API, right?****
>>
>>  ********
>>
>>
>>
>> FWIW, while we're subject to Hibernate unpredictability until our API is
>> rewritten, having changes to objects sometimes persisted before asking the
>> API to save them is a smaller problem than calling create or save on an
>> object and not having those changes reliably persisted.  If the latter is
>> ****
>>
>> happening (as your issue suggests), then we need to fix it.****
>>
>>  ****
>>
>> -Burke****
>>
>>  ********
>>
>>
>>
>> On Thu, Dec 29, 2011 at 11:30 AM, McKee, Steven Jay <[email protected]>**
>> **
>>
>> wrote:****
>>
>> I?m currently running OpenMRS 1.7, and I?m seeing an intermittent issue
>> across Hibernate sessions in our CHICA code:****
>>
>>  ********
>>
>>
>>
>> 1.       Session one inserts a new PatientState (CHICA specific****
>>
>> table/object).********
>>
>>
>>
>> 2.       A new thread is created to do some processing on the****
>>
>> PatientState.  The patient state ID is passed to the thread.********
>>
>>
>>
>> 3.       Session two is created in the new thread and tries to get a****
>>
>> PatientState object based on the patient state ID.****
>>
>> 4.       The PatientState object is coming back null.****
>>
>>  ********
>>
>>
>>
>> It seems as though session one has not committed the new patient state and
>> session two is trying to access it.  What is the best Hibernate mechanism
>> to use to ensure the patient state is committed to the database before
>> session two tries to access it?  Keep in mind the PatientState object is*
>> ***
>>
>> being accessed outside the DAO layer.****
>>
>>  ****
>>
>> Thanks,****
>>
>> Steve****
>>
>>  ****
>>  ------------------------------
>>
>> 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
>> ****
>>
>>  ****
>>  ------------------------------
>>
>> 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
>> ****
>>
>> ** **
>>  ------------------------------
>>
>> 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]****
>>
>>
>> _________________________________________
>>
>> 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
>
>
> ------------------------------
> 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