persistence@glassfish.java.net

Re: caching bug?

From: Jeffrey Blattman <jeffrey.blattman_at_gmail.com>
Date: Fri, 10 Aug 2007 15:52:12 -0700

tell me this,

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);
C c = a.getC(someId);

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.
>>>>
>>>>
>>>
>