tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <david.blev...@visi.com>
Subject Re: em.clear() in a non transactional context
Date Thu, 26 Feb 2009 17:53:19 GMT

On Feb 20, 2009, at 12:01 AM, David Blevins wrote:

> On Feb 18, 2009, at 1:00 AM, Jean-Sébastien Scrève wrote:
>
>> 	@PersistenceContext(unitName = "MyUnit", type =
>> PersistenceContextType.EXTENDED)
>> 	private EntityManager em;
>
>
> Aha.  I had assumed that we were talking about  
> PersistenceContextType.TRANSACTION.
>
> Going to have to dig in the spec to see what the considerations may  
> be for PersistenceContextType.EXTENDED.  Off hand I'd guess that  
> calling clear outside a transaction is ok provided you are ok with  
> any changes being discarded and never persisted.

It seems that is the case.  I've gone through the spec and don't see  
any issues with clear() on an EXTENDED persistence context.

I've gone ahead and checked in that change, so the clear will detach  
all of the entities in the EXTENDED persistence context.


-David



>>
>> As you can see, I use an extended persistence context. The "attach"  
>> method I
>> defined is used to browse "MyEntity" relations. After navigating  
>> through
>> "MyEntity" relations, I call the cancel() method on the stateful  
>> session
>> bean. However, after that, I'm still able to browse relations. I  
>> expected
>> lazy loading exceptions to occur.
>> Hibernate is the Persistence provider I use. I hope you better  
>> understand my
>> problem... Am I doing something wrong ?
>>
>> Many thanks !
>>
>> Jean-Sébastien Scrève.
>>
>>
>> David Blevins wrote:
>>>
>>> [note to future readers: this content does not apply to EXTENDED
>>> persistence contexts]
>>>
>>> On Feb 11, 2009, at 8:14 AM, Bharath Ganesh wrote:
>>>
>>>> The clear method would detach all the entities from the EM.  
>>>> Whenever
>>>> you
>>>> invoke a method on an EM, in a non-transactional context,
>>>> semantically it
>>>> would mean you are using a new EM every time. The EM cache would be
>>>> cleaned
>>>> up after every method call. I am not sure how this is implemented  
>>>> in
>>>> OpenEJB, but ideally in a transactional context when your invoke a
>>>> method on
>>>> the EM, during the preProcess the container would create the
>>>> underlying JPA
>>>> provider's EM and at the end during postProcess would close that  
>>>> EM.
>>>>
>>>> So em.clear() really doesn't make sense when you are using the EM  
>>>> in a
>>>> non-transactional context.
>>>
>>> Thanks for posting!  That sums up my thoughts as well.
>>>
>>> More comments below.
>>>
>>>> On Wed, Feb 11, 2009 at 4:14 PM, Jean-Sébastien Scrève <
>>>> jean-sebastien.screve@atosorigin.com> wrote:
>>>>
>>>>>
>>>>> Ok thanks David.
>>>>>
>>>>> Let me explain the circumstances of my question :
>>>>>
>>>>> I have a Stateful session bean. All methods are non transactional.
>>>>> I only
>>>>> want to browse entities.
>>>>>
>>>>> Let's say I have a reference to an entity. I call the clear()
>>>>> method on the
>>>>> session bean.
>>>>> After that, it's still possible to browse my entity relations as
>>>>> the clear
>>>>> method did nothing.
>>>
>>> We should be closing the EntityManager immediately after the call is
>>> made for usage outside a transaction which should cause all the
>>> objects to detach.  If that is not happening then there is  
>>> definitely
>>> a bug.
>>>
>>> If you could tell me exactly what calls you're making on the
>>> EntityManager outside of a transaction that would help.
>>>
>>> Here's how the JTA EntityManager should be working outside a
>>> transaction:
>>>
>>>    // return a new EntityManager instance
>>>    public EntityManager getDelegate();
>>>
>>>    // throw new TransactionRequiredException()
>>>    public void persist(Object entity);
>>>    public <T>T merge(T entity);
>>>    public void remove(Object entity);
>>>    public void flush();
>>>    public void lock(Object entity, LockModeType lockMode);
>>>    public void refresh(Object entity);
>>>
>>>    // Create a new EntityManager instance, call method, close and
>>> discard the EntityManager
>>>    public <T>T find(Class<T> entityClass, Object primaryKey);
>>>    public <T>T getReference(Class<T> entityClass, Object  
>>> primaryKey);
>>>    public void setFlushMode(FlushModeType flushMode);
>>>    public FlushModeType getFlushMode();
>>>
>>>    // do nothing
>>>    public void clear();
>>>    public void joinTransaction();
>>>    public void close();
>>>
>>>    // return false
>>>    public boolean contains(Object entity);
>>>
>>>    // return true
>>>    public boolean isOpen();
>>>
>>>    // Create a new EntityManager instance, create query
>>>    // close and discard EntityManager after first call to
>>> getResultList(), getSingleResult() or executeUpdate()
>>>    public Query createQuery(String qlString);
>>>    public Query createNamedQuery(String name);
>>>    public Query createNativeQuery(String sqlString);
>>>    public Query createNativeQuery(String sqlString, Class
>>> resultClass);
>>>    public Query createNativeQuery(String sqlString, String
>>> resultSetMapping);
>>>    private Query proxyIfNoTx(EntityManager entityManager, Query
>>> query);
>>>
>>>    // throw new IllegalStateException()
>>>    // this is always the case for a JTA EntityManager
>>>    public EntityTransaction getTransaction();
>>>
>>>>>
>>>>>
>>>>> I really want to clear references to all entities to avoid memory
>>>>> leaks.
>>>>>
>>>>> I know I can call getDelegate but this is not really a standard  
>>>>> way
>>>>> to
>>>>> proceed.
>>>>> I'd like to have a standard answer to that question.
>>>>>
>>>>> The specification says the clear() method make all entities
>>>>> detached. It
>>>>> does not specify transactional conditions.
>>>>>
>>>>> Any idea ? Don't you think you could remove the transaction test  
>>>>> in
>>>>> the
>>>>> clear() method ? Maybe the specification should clarify some
>>>>> things...
>>>
>>> Calling getDelegate() or removing the transaction check in clear()  
>>> is
>>> simply going to get you a brand new EntityManager instance if done
>>> outside a transaction.  So the clear() would not have the affect you
>>> want.
>>>
>>> We need to figure out why the underlying EntityManager may not be
>>> getting closed.  Also, what JPA provider are you using?
>>>
>>>
>>> -David
>>>
>>>
>>>
>>>>> Thanks in advance !
>>>>>
>>>>> Jean-Sébastien Scrève.
>>>>>
>>>>>
>>>>> David Blevins wrote:
>>>>>>
>>>>>>
>>>>>> On Feb 2, 2009, at 9:07 AM, Jean-Sébastien Scrève wrote:
>>>>>>
>>>>>>> I have a question regarding the em.clear() in the  
>>>>>>> JtaEntityManager
>>>>>>> class.
>>>>>>> Before clearing the context, OpenEJB checks that a transaction
 
>>>>>>> is
>>>>>>> currently
>>>>>>> active.
>>>>>>> Is there any reason for that ? I don't see any mention of this
>>>>>>> behavior in
>>>>>>> the specification.
>>>>>>
>>>>>> It has to do with the lifecycle of a
>>>>>> PersistenceContextType.TRANSACTION EntityManager.  The long and
>>>>>> short
>>>>>> of it is that the JtaEntityManager will create an EntityManager
>>>>>> (PersistenceContext) at the beginning of a transaction and  
>>>>>> destroy
>>>>>> it
>>>>>> at the end of the transaction.  So when no transaction is active,
>>>>>> there is no EntityManager to call clear() on and no
>>>>>> PersistenceContext
>>>>>> data to clear.
>>>>>>
>>>>>> -David
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> View this message in context:
>>>>> http://www.nabble.com/em.clear%28%29-in-a-non-transactional-context-tp21793624p21951943.html
>>>>> Sent from the OpenEJB User mailing list archive at Nabble.com.
>>>>>
>>>>>
>>>
>>>
>>>
>>
>> -- 
>> View this message in context: http://www.nabble.com/em.clear%28%29-in-a-non-transactional-context-tp21793624p22074752.html
>> Sent from the OpenEJB User mailing list archive at Nabble.com.
>>
>>
>
>


Mime
View raw message