persistence@glassfish.java.net

Re: Cannot see newly created object

From: Markus KARG <markus.karg_at_gmx.net>
Date: Tue, 01 Jul 2008 22:23:26 +0200

Marina
> 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.
I thought so, too. But why not getting an Exception when doing
em.refresh(myEntity)? Is it allowed to refresh a detached entity?

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


-- 
http://www.xing.com/go/invita/58469