persistence@glassfish.java.net

Re: Cannot see newly created object

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Tue, 01 Jul 2008 12:55:07 -0700

Markus,

Can it be that you are accessing a detached reference when you are accessing it
the 2nd time? If EM is transactional, and it's container-managed (i.e. injected
or looked up directly, not through EMF), all instances become detached after commit.

thanks,
-marina

Mitesh Meswani wrote:
> Markus KARG wrote:
>
>> Mitesh,
>>
>>>>> This opens some other questions... You can not call em.refresh() on
>>>>> a detached object (results in an exception) so how is this managed
>>>>> entity getting into the second SB and why is there an existing
>>>>> Persistence Context in the second SB if you are using the default
>>>>> (TRANSACTION) Persistence Context type and there is not a
>>>>> transaction spanning the 2 SB calls?
>>>>> How is this second SB performing the 'lookup' ?
>>>>
>>>> The SBs are not related. As I said, SB1 send JMS, JMS triggers MDB.
>>>> SB2 is triggered manually by the user. SB1 and SB2 are not related.
>>>>
>>>> The entity is kept by SB2 (which is a stateful SB) by just keeping
>>>> it as a member variable. In the constructor, SB2 does
>>>> em.find(Entity.class, PK) to find it, and then keeps it. When the
>>>> client is calling SB2's business method, em.refresh(entity) is
>>>> performed. The object does not get detached, obviously. To be able
>>>> to do the em.find(PK) in the constructor, the client provides the PK.
>>>
>>> If SB2 is stateful SB then it explains the behavior. The default type
>>> of PersitenceContext for stateful bean is Extended. Hence find
>>> (correctly) gives you the "stale" instance and refresh solves the issue.
>>
>> So that means that SLSB, SFSB and MDB have different defaults for
>> their PersistenceContext behaviour. In the JPA spec I found: "If the
>> type element is not specified, a transaction-scoped persistence
>> context is used.". So there must be another chapter of the spec that
>> contains the part with the stateful default. Can you point me to where
>> I can find that? :-)
>
> I was wrong. Sorry for the confusion.
>
> I think answer to Gordon's questions above should help move forward.
>
> -Mitesh
>
>>
>> -Markus
>>
>>>
>>> -Mitesh
>>>
>>>>
>>>> So, the entity itself is not moved around, just it's PK.
>>>>
>>>>> I can not tell you why the refresh is needed. TopLink's cache will
>>>>> be updated with the changes from the MDB transaction and subsequent
>>>>> Persistence Contexts will see this update. That is why I was
>>>>> asking the questions about the transactions and the types of
>>>>> Persistence Contexts in the Session Beans. Based on your symptoms
>>>>> it points to the second SB using a pre-MDB Persistence Context that
>>>>> contains an old version of the Parent object. Persistence Contexts
>>>>> are an intentionally isolated object space and will not have the
>>>>> changes from another Persistence Context or transaction.
>>>>
>>>> So that means that you think there is a bug in TopLink? I mean,
>>>> either my code is right or it is not. So either there is a bug in
>>>> TopLink, or there is not. Since I am just a JPA novice, how should I
>>>> know whether to report it as a bug or not? I need you to be the
>>>> judge. :-)
>>>>
>>>> Thanks
>>>> Markus
>>>>
>>>>> --Gordon
>>>>>
>>>>> Markus KARG wrote:
>>>>>
>>>>>> Gordon,
>>>>>>
>>>>>>> Try clearing the Persistence Context in the Session Bean that is
>>>>>>> attempting to see the changes from the MDB before performing the
>>>>>>> find and the changes should then be loaded into the Persistence
>>>>>>> Context.
>>>>>>
>>>>>> As I have seen the code is not exactly as I thought. The stateful
>>>>>> session bean that does the lookup is not keeping the PK but the
>>>>>> actual entity. So there is no em.find() actually. I added a
>>>>>> em.refresh(entity) now before the call of the lookup. Guess what,
>>>>>> that is working.
>>>>>>
>>>>>> But unfortunately, I have not understood why that refresh is
>>>>>> needed. I thought that as soon as I set both sides of the
>>>>>> relationship that will update the object, but it seems it does
>>>>>> not. Can you give me a very brief description why that refresh()
>>>>>> is needed? I mean, isn't TopLink's cache "seeing" that another TX
>>>>>> changed the number of children in the relationship?
>>>>>>
>>>>>> Thanks a lot!
>>>>>> Markus
>>>>>>
>>>>>>> --Gordon
>>>>>>>
>>>>>>> Markus KARG wrote:
>>>>>>>
>>>>>>>> I have not changed the transactional settings, so the defaults
>>>>>>>> apply in both, the SB and the EB.
>>>>>>>> AFAIK the default is that a TX is automatically started and
>>>>>>>> finished around the invocation, isn't it?
>>>>>>>>
>>>>>>>> Gordon Yorke schrieb:
>>>>>>>>
>>>>>>>>> Hello Markus
>>>>>>>>> What are the transactional boundaries for the listening
>>>>>>>>> SB? Is the em you are accessing in the listener in a
>>>>>>>>> transaction and reading transactional data?
>>>>>>>>> --Gordon
>>>>>>>>>
>>>>>>>>> Markus KARG wrote:
>>>>>>>>>
>>>>>>>>>> I forgot to mention: Exactly the same code executed from
>>>>>>>>>> within a session bean results in the new child beeing listed
>>>>>>>>>> correctly.
>>>>>>>>>>
>>>>>>>>>> So what difference is between a MDB and a SB?
>>>>>>>>>>
>>>>>>>>>> Thanks! :-)
>>>>>>>>>> Markus
>>>>>>>>>>
>>>>>>>>>> Markus Karg schrieb:
>>>>>>>>>>
>>>>>>>>>>> I have a strange problem and need your kind help. :-)
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> In GlassFishv2ur2, I am running a session bean that does:
>>>>>>>>>>>
>>>>>>>>>>> parent = em.find(ParentEntity.class, 1000).getSingleResult();
>>>>>>>>>>> parent.getChildren();
>>>>>>>>>>>
>>>>>>>>>>> which lists the content of a OneToMany relationship.
>>>>>>>>>>>
>>>>>>>>>>> Now a message driven bean does:
>>>>>>>>>>>
>>>>>>>>>>> parent = em.find(ParentEntity.class, 1000).getSingleResult();
>>>>>>>>>>> child = new ChildEntity(parent); // Implicitly sets "One"-Side
>>>>>>>>>>> parent.getChildren().add(child); // Explicitly sets "Many"-Side
>>>>>>>>>>> em.persist(child);
>>>>>>>>>>>
>>>>>>>>>>> When I go to the DBMS, I can see the row of the new child
>>>>>>>>>>> including all fields. The child is correctly linked with the
>>>>>>>>>>> parent.
>>>>>>>>>>>
>>>>>>>>>>> But when running the listing again:
>>>>>>>>>>>
>>>>>>>>>>> parent = em.find(ParentEntity.class, 1000).getSingleResult();
>>>>>>>>>>> parent.getChildren();
>>>>>>>>>>>
>>>>>>>>>>> Then still I do not see the new child. To make it appear, I
>>>>>>>>>>> must undeploy and deploy. That is very weird, since it can be
>>>>>>>>>>> seen in the database table, and I have set both sides of the
>>>>>>>>>>> relationship as you can see in the code snippet.
>>>>>>>>>>>
>>>>>>>>>>> Looks like a cache problem, but I just do not understand how
>>>>>>>>>>> to solve it.
>>>>>>>>>>>
>>>>>>>>>>> Has anybody an idea what the cause is and how to get rid of it?
>>>>>>>>>>>
>>>>>>>>>>> Thanks a lot! :-)
>>>>>>>>>>> Markus
>>>>>>>>>>>
>>>>>>>>>>> QUIPSY QUALITY GmbH & Co. KG
>>>>>>>>>>> Ein Unternehmen der MES-Gruppe
>>>>>>>>>>> Stuttgarter Strasse 23
>>>>>>>>>>> D-75179 Pforzheim
>>>>>>>>>>> Tel: 07231-9189-52
>>>>>>>>>>> Fax: 07231-9189-59
>>>>>>>>>>> www.quipsy.de
>>>>>>>>>>> karg_at_quipsy.de
>>>>>>>>>>> Registergericht Mannheim HRA 701214
>>>>>>>>>>> Geschäftsführer: Nils Schroeder
>>>>>>>>>>>
>>>>>>>>>>> Diese E-Mail enthält persönliche, vertrauliche und vor
>>>>>>>>>>> Weitergabe geschützte Informationen und ist ausschließlich
>>>>>>>>>>> für den vorgesehenen o.g. Empfänger (Adressaten) bestimmt.
>>>>>>>>>>> Falls Sie diese E-Mail versehentlich erhalten haben und nicht
>>>>>>>>>>> der vorgesehene Empfänger sind, bitten wir Sie, die E-Mail
>>>>>>>>>>> und deren Anhänge nicht aufzubewahren, nicht zu
>>>>>>>>>>> vervielfältigen, nicht zu nutzen und nicht weiterzugeben.
>>>>>>>>>>> Bitte informieren Sie uns als Absender über diesen
>>>>>>>>>>> Zustellungsfehler und löschen Sie die E-Mail.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>