openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Wes Wannemacher <w...@wantii.com>
Subject Re: Does merging cause all "dirty" entities to be written to the database?
Date Tue, 27 Apr 2010 14:52:18 GMT
Sorry, Mike, you are right, example 8.2 does indicate my issue.

The unit test that I pasted does not place the *change* of the second
entity inside of the transaction, but the second entity is managed. If
changes to all persistent fields of all managed entities are saved on
each transaction commit, I'd definitely have to use something like
transfer objects.

Still, I'm curious how other people might address concurrency...

-Wes

On Tue, Apr 27, 2010 at 10:47 AM, Wes Wannemacher <wesw@wantii.com> wrote:
> Thanks for looking at this Mike,
>
> The main question/concern I have is concurrency...
>
> Imagine simultaneous users hitting a web-app. A call to merge in one
> users request, does that save changes to an entity that another user's
> request is editing?
>
> Right now, I take my JPA entities and I expose them to my (struts)
> views and when the user submits a form, getters/setters get called on
> the (potentially managed) entities. The action may or may not save the
> changes, but if another user's request leads to a merge call, then
> would that lead to changes being saved on all entities managed by the
> entity manager?
>
> I will spend some time looking through the docs and the spec, but if
> anyone follows a similar use-case, I'd like to know how they handle
> this... Should I detach the entities after retrieving them? Should I
> copy the properties of the entities into a transfer object?
>
> In addition, if changes to all managed entities are saved when an
> entity is merged, then what is the point of having cascade
> configurations?
>
> A quick re-read of your email, and I want to be clear that you
> understood that unit test. The merge call is a different entity than
> the one that is tested... The pseudo-code of the unit test is this -
>
> retrieve EntityA
> retrieve EntityB
> change EntityA.someProp
> change EntityB.someProp
> save Entity*A* (through merge call)
> retrieve a new copy of Entity*B*
> check EntityB.someProp matches what it used to be (since EntityB was
> never explicitly saved)
>
> If you were addressing it correctly, I apologize for reiterating.
>
> -Wes
>
> On Tue, Apr 27, 2010 at 9:54 AM, Michael Dick <michael.d.dick@gmail.com> wrote:
>> Hi Wes,
>>
>> Thanks for putting the example on pastebin, it's much easier to read the
>> code there than in an email.
>>
>> The test should not pass, the row should be updated in the database when you
>> commit the transaction. You've obtained an instance of your entity and
>> modified it's contents. The entity is managed at this point, meaning that
>> JPA is tracking the changes you make, and those changes will be updated in
>> the database when the transaction commits.
>>
>> Even if the entity was not managed (for example if you called em.clear()
>> before updating it), the merge operation would take any changes and copy
>> them into a new managed instance of the entity. The contents of that managed
>> entity would be updated in the database when the transaction commits.
>>
>> There's more information in the JPA spec itself (look for managed entities)
>> or in the OpenJPA manual
>> http://openjpa.apache.org/builds/latest/docs/manual/manual.html#jpa_overview_em_lifeexamples
>> (example
>> 8.2 hits your case fairly closely).
>>
>> hth
>> -mike
>>
>> On Tue, Apr 27, 2010 at 8:11 AM, Wes Wannemacher <wesw@wantii.com> wrote:
>>
>>> bump...
>>>
>>> I think the first time I posted this message, pastebin went offline,
>>> but the unit test is back up and visible...
>>>
>>> http://pastebin.com/kDw1rX7e
>>>
>>> What I'd really like to know is whether this test should ever pass,
>>> and if not, where can I read about the details of the merge call. If
>>> it should pass, that would be interesting as well because I would know
>>> to go take it up with the Spring folks.
>>>
>>> -Wes
>>>
>>> On Fri, Apr 23, 2010 at 1:57 PM, Wes Wannemacher <wesw@wantii.com> wrote:
>>> > Hello, I've been lurking on this list for a while and i have been a
>>> > happy user for OpenJPA for a year or so. However, I came across a
>>> > situation recently which kind of suprised me.
>>> >
>>> > Imagine that both CDO_ConditionCode and CDO_CageCode are enhanced
>>> > entities that do not a relationship. These beans have an @Id field (of
>>> > type String) and a description (of type String). Here is the
>>> > interesting snippet of a unit test I wrote to check out this behavior
>>> > ->
>>> >
>>> > CDO_ConditionCode retrievedCondCode = em.find(CDO_ConditionCode.class,
>>> "00");
>>> > CDO_CageCode retrievedCageCode = em.find(CDO_CageCode.class, "00000");
>>> >
>>> > retrievedCondCode.setDescription("new description");
>>> > retrievedCageCode.setDescription("new description");
>>> >
>>> > em.getTransaction().begin();
>>> > retrievedCageCode = em.merge(retrievedCageCode);
>>> > // em.flush(); // with or without the flush, this test fails
>>> > em.getTransaction().commit();
>>> >
>>> > CDO_ConditionCode otherRetrievedCondCode =
>>> > em.find(CDO_ConditionCode.class, "00");
>>> > assertTrue("expected value not to change", "description of
>>> > 00".equals(otherRetrievedCondCode.getDescription()));
>>> >
>>> > I noticed it while working on an oracle database. I had a breakpoint
>>> > in one section of my code and I was trying to figure out an unrelated
>>> > problem. While the app was hanging at the breakpoint, I noticed that
>>> > changes to an unmerged entity had been written to the database. If you
>>> > want to see the full unit test, it will be available here for a little
>>> > while -
>>> >
>>> > http://pastebin.com/kDw1rX7e
>>> >
>>> > In the application, most of the JPA operations are hidden behind a DAO
>>> > that delegates to Spring's JpaTemplate. However, I wrote the unit test
>>> > to get rid of the JpaTemplate to see if hte problem was with my DAO,
>>> > Spring or OpenJPA. In addition to removing the JpaTemplate, I also ran
>>> > the unit test using EclipseLink 2.0.2, which failed at the assert,
>>> > just like OpenJPA. That leads me to believe that this isn't
>>> > necessarily a *problem*, but it is that maybe I misunderstand the
>>> > behavior of a call to merge. Can someone explain to me why this fails,
>>> > or just point me to a section that would help me understand why a
>>> > merge to one entity causes the other entity to be saved to the
>>> > database. Or, if this should succeed, I will look further at Spring
>>> > being the culprit (even though I eliminated the JpaTemplate, I did not
>>> > eliminate Spring's LocalContainerEntityManagerFactoryBean).
>>> >
>>> > Thanks guys!
>>> >
>>> > -Wes
>>> >
>>> > --
>>> > Wes Wannemacher
>>> >
>>> > Head Engineer, WanTii, Inc.
>>> > Need Training? Struts, Spring, Maven, Tomcat...
>>> > Ask me for a quote!
>>> >
>>>
>>>
>>>
>>> --
>>> Wes Wannemacher
>>>
>>> Head Engineer, WanTii, Inc.
>>> Need Training? Struts, Spring, Maven, Tomcat...
>>> Ask me for a quote!
>>>
>>
>
>
>
> --
> Wes Wannemacher
>
> Head Engineer, WanTii, Inc.
> Need Training? Struts, Spring, Maven, Tomcat...
> Ask me for a quote!
>



-- 
Wes Wannemacher

Head Engineer, WanTii, Inc.
Need Training? Struts, Spring, Maven, Tomcat...
Ask me for a quote!

Mime
View raw message