persistence@glassfish.java.net

Re: Updated Objects Are Not Being Persisted

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Wed, 16 Jul 2008 09:42:21 -0400

My guess is that you read a 'Job' into TopLink process it and set it's
status to 'Done'. Then external to TopLink another application or
process changes the status to something else. TopLink is then asked to
load this 'Job' and update it's status back to 'Done'. The problem is
TopLink finds the object in the cache with the status set as 'Done' and
therefore does not detect the update as a change and does not issue any SQL.

Before making any changes think about how often this can happen in your
application and if it happens in this manner.

If the application is "read mostly" then the application can really
benefit from the cache but based on your description it seems this
application is not "read mostly". If the application is "write mostly"
(as many writes to the 'Job' class as there are reads) then you will
want to change your cache settings to disable the cache. This is done
through the persistence unit property
"toplink.cache.shared.<EntityName>" "false" or
"toplink.cache.shared.default" "false" if all of the entities are "write
mostly". This will have better performance then always refreshing the
object before the change.

--Gordon

xedus wrote:
> i'm using TopLink, version: Oracle TopLink Essentials - 2.0.1
> the method always returns true, there were no exceptions.
>
> the status in the database will be updated just fine, until the value
> changed manually, or presumingly another operating had had taken place on
> the same row/table.... after that, the value would never be update in the
> database, even after a flush! however i got it working by adding a refresh
> before i update the status of the object,.... but i don't know how did that
> fix it!
> i would have posted the code here but it won't be pritty. if you would like
> to have a look ,here is the link to my thread:
> http://forum.java.sun.com/thread.jspa?messageID=10340227
> http://forum.java.sun.com/thread.jspa?messageID=10340227
>
> i'll try to turn the logging level to fine, and test again,
>
> thank you
>
>
> Gordon Yorke-2 wrote:
>
>> Which Oracle TopLink are you using? Can you turn on logging using the
>> persistence unit property "toplink.logging.level" "FINE"? Are you seeing
>> the status getting updated on the database through the EntityManager
>> calls? Are both components using the same persistence unit? Are you
>> sure that a transaction is active? What value is the method
>> "markJobAsDone" returning (true or false)?
>> --Gordon
>>
>> xedus wrote:
>>
>>> greetings,
>>>
>>>
>>>
>>> you mean doing a refresh before doing find to update?
>>> is there a way to prevent caching which i think the reason for this
>>> problem....?
>>>
>>> thank you
>>>
>>>
>>> Adam Bien wrote:
>>>
>>>
>>>> Hi Xedus,
>>>>
>>>> and you do it inside a TX? Try to clear the EM before reading,
>>>>
>>>> adam
>>>> xedus schrieb:
>>>>
>>>>
>>>>> Hello everyone,
>>>>>
>>>>> i'm runing a printing queue web service on glassfish v2, the clients
>>>>> ask
>>>>> for
>>>>> thier printing jobs and the server send it to them. After each
>>>>> successful
>>>>> print the client invoke a web service method to flag that certain job
>>>>> as
>>>>> being "done" so that the client will not have it sent to him again the
>>>>> next
>>>>> round when it askes for available printg jobs...
>>>>>
>>>>> it hapens many times that the new status "done" will not persist to the
>>>>> data
>>>>> base which leads to the pritnig job being sent over and over again.
>>>>>
>>>>> i tried container managed transactions and bean managed transaction
>>>>> with
>>>>> the
>>>>> same result. i even tried em.flush(), but no luck.....
>>>>>
>>>>> i'm using oracle toplink..
>>>>>
>>>>> here is how the code looks like .....
>>>>>
>>>>> .
>>>>> .
>>>>> .
>>>>> private void persist(Object obj){
>>>>> try{
>>>>> //ut.begin();
>>>>> //em.merge(obj);
>>>>> em.persist(obj);
>>>>> //ut.commet();
>>>>> }catch(Exception ex){ ...}
>>>>> }
>>>>> @webmethod
>>>>> public boolean markJobAsDone(long jobID){
>>>>> try{
>>>>> PrintingJob aJob = em.find(PrintingJob.class,jobID);
>>>>> aJob.setStatus("done");
>>>>> persist(aJob);
>>>>> }catch(Exception ex){
>>>>> return false;
>>>>> }
>>>>> return true;
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> also the clients are asking for jobs every 30 seconds
>>>>> another question, is there any other aproach to these queues and jobs?
>>>>>
>>>>> please help
>>>>>
>>>>>
>>>>>
>>>>> i just wanted to add that i can recreate the problem simply by changing
>>>>> the
>>>>> status of a job manualy form "SQL Developer" for example from "Done" to
>>>>> "pending" and the job will keep beibg sent and will never be set to
>>>>> "Done"
>>>>> again....
>>>>>
>>>>>
>>>>>
>>>>>
>>>> --
>>>> Consultant, Author, Java Champion
>>>>
>>>> Homepage: www.adam-bien.com
>>>> Weblog: blog.adam-bien.com
>>>> eMail: abien_at_adam-bien.com
>>>> Mobile: 0049(0)170 280 3144
>>>>
>>>> Books: Enterprise Architekturen (ISBN: 393504299X),
>>>> Java EE 5 Architekturen (ISBN: 3939084247),
>>>> J2EE Patterns, J2EE Hotspots, Enterprise Frameworks and Struts
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>
>