persistence@glassfish.java.net

Re: caching bug?

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Fri, 10 Aug 2007 16:01:05 -0700

Jeffrey Blattman wrote:
> tell me this,
>

Is it a Java SE or Java EE app? If the latter, is it a SLSB or a SFSB or
something else?

I'm asking that to understand the EM/TX behavior. If it's an SE or SFSB or
something else that uses the *same* EM (i.e. an extended persistence context),
than nothing is being adjusted if you don't do it yourself.


> t1 i do:
>
> C c = em.find(C.class, someId);
> em.remove(c);
>
> then in t2 i do:
>
> A a = em.find (A.class, ...);
>
> then in t3 i do:
>
> em.merge(a);

Why do you need a merge()? Which fields are you merging?

> C c = a.getC(someId);

The ref might still be there, but you shouldn't be able to access it (or it can
be persisted again, if the relationship from A to C is marked for cascade
merge/persist/all and the merge logic identifies someId as a new instance).

>
> where getC() accessed the collection field of A, should C with ID someId
> be found?
>
> Marina Vatkina wrote:
>
>> Hi Jeffrey,
>>
>> Jeffrey Blattman wrote:
>>
>>> hi marina,
>>>
>>> i can't believe this can be so confusing. to remove a C, am i
>>> supposed to do ...
>>>
>>> 1.
>>>
>>> A a = em.find(A.class, ...);
>>> a.getCs().remove(c);
>>
>>
>> Yes.
>>
>>>
>>> or can i only do:
>>>
>>> 2.
>>>
>>> C c = em.find(C.class, ...);
>>> em.remove(c);
>>
>>
>> You can if you then refresh 'a' or disable the cache, and C holds the
>> FK to A.
>>
>>>
>>> ? you are saying that if i do #2, i have to manually fix the
>>> relationship by finding the A that contains the C and removing it
>>> from the collection? if that's true, then obviously #2 is not the
>>> correct thing to do ... ?
>>>
>>> i am trying to do #1, which appears to work, but when i do an
>>> em.remove() on the A to clean up after the test, i get foreign key
>>> violation.
>>
>>
>> That's strange... you need to fix 'a' in the same transaction. You
>> can also do em.refresh(a), but if you already removed 'c', how would
>> you find the 'a'?
>>
>> thanks,
>> -marina
>>
>>>
>>> Marina Vatkina wrote:
>>>
>>>> No, it's called non-managed relationships. You need to clean them up
>>>> on all sides (unless that particular side is responsible for cascade
>>>> removal).
>>>>
>>>> But yes, it's a side-effect of the caching.
>>>>
>>>> thanks,
>>>> -marina
>>>>
>>>> Jeffrey Blattman wrote:
>>>>
>>>>> Jeffrey Blattman wrote:
>>>>>
>>>>>> i have entity A that has a collection of entities C
>>>>>>
>>>>>> /public class A ...
>>>>>> private List<C> cs = ...
>>>>>> /
>>>>>> so i do an em.remove(C.class, cid). now i want to verify that the
>>>>>> C with ID cid is removed. so i do:
>>>>>>
>>>>>> /C c = em.find(C.class, cid);
>>>>>> /
>>>>>> this returns null, as expected. now i do this ...
>>>>>>
>>>>> forgot to mention ... in the above find(), i see a select as
>>>>> expected ...
>>>>>
>>>>>> /A a = em.find(A.class, ...);
>>>>>> List<C> cs = a.getCs();
>>>>>> /
>>>>>
>>>>>
>>>>>
>>>>> but here i see no access to the DB.
>>>>>
>>>>>> and i page through the cs collection, i find that the C with ID
>>>>>> cid still exists. all of the above em.* operations are done in
>>>>>> separate transactions. is this a caching bug? i can provide a test
>>>>>> case if necessary.
>>>>>
>>>>>
>>>>>
>>>>
>>