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 Wed, 11 Feb 2009 18:58:41 GMT
[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.
>>
>>


Mime
View raw message