Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Spring: Attempting to execute an operation on a closed EntityManager.

Ok, so reading all these, the EntityManager obtained via
@PersistenceContext is a Shared EntityManager which is a thread-safe
proxy!

./tch



On Sun, Sep 28, 2008 at 6:56 PM, Manuel de Brito Fontes
<aledbf@xxxxxxxxx> wrote:
> Hi Tim,
>        Yes also suposse that an EntityManager is thread safe, but see this:
> http://forum.springframework.org/showthread.php?t=33804 or this
> https://blueprints.dev.java.net/bpcatalog/ee5/persistence/webonlyapp.html (this
> are only two references, but in the spring forum exists many more) and the
> spec don't define that a EntityManager has to be thread safe.
> About the stress, use selenium-grid or something similiar and create more
> than 70 simultanous clients doing read/save and you will see the mentioned
> behavior with the pure JPA approach.
>
> On 28-09-2008, at 11:15, Tim Hollosy wrote:
>
>> Thanks Manuel,
>> This is valuable information. So let me summarize the advice I've gotten
>> so far.
>>
>> There are 2 camps: The Template camp and the Pure JPA @PersistenceContext
>> camp.
>>
>> When using the template approach you manage a factory for each DAO
>> implementation, but when using the @PersistenceContext the container
>> manages the EntityManagerFactory.
>>
>>
>> Now, "The pure JPA setup that you can find in examples works fine,
>> until you stress the DAO with multiples simultaneous clients" is
>> interesting, though anecdotal. I understand that you will run into
>> thread issues using @PersistenceUnit but I thought @PersistenceContext
>> was supposed to be safe. I suppose I'll have to do my own test, but
>> I'm still leaning more towards using @PersistenceContext just for the
>> beauty of the code. Thank you very much for posting your full Dao Impl
>> though that's quite helpful.
>>
>>
>> ./tch
>>
>>
>>
>> On Sat, Sep 27, 2008 at 10:23 PM, Manuel de Brito Fontes
>> <aledbf@xxxxxxxxx> wrote:
>>>
>>> Hi Tim,
>>>      The pure JPA setup that you can find in examples works fine, until
>>> you stress the DAO with multiples simultaneous clients. In my case I
>>> receive
>>> errors when trying to save/delete data. This is related with the fact
>>> that
>>> the EntityManager defined in the DAO's is the same for all the
>>> references.
>>> -
>>>
>>> http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/orm/jpa/JpaTemplate.html#method_summary
>>>      " NOTE: JpaTemplate mainly exists as a sibling of JdoTemplate and
>>> HibernateTemplate, offering the same style for people used to it. For
>>> newly
>>> started projects, consider adopting the standard JPA style of coding data
>>> access objects instead, based on a "shared EntityManager" reference
>>> injected
>>> via a Spring bean definition or the JPA PersistenceContext annotation.
>>> (Using Spring's SharedEntityManagerBean /
>>> PersistenceAnnotationBeanPostProcessor, or using a direct JNDI lookup for
>>> an
>>> EntityManager on a Java EE 5 server.)"
>>>
>>> This is way I prefer the JpaTemplate in which I inject the
>>> EntityManagerFactory (this generates a new instance of EntityManager by
>>> each
>>> DAO)
>>> To avoid the lazy initialization problem only use OpenEntityManagerInView
>>> if
>>> you are creating an Web Application
>>>
>>> Here is an example of the generic dao and one example:
>>>
>>> @Repository
>>> public class GenericDaoJPAImpl<T, PK extends Serializable> extends
>>> JpaDaoSupport implements GenericDao<T, PK> {
>>>
>>>      private Class<T> cPersistentT;
>>>
>>>      @Autowired
>>>      private EntityManagerFactory emf;
>>>
>>>      @SuppressWarnings("unchecked")
>>>      public GenericDaoJPAImpl(final Class<T> cType) {
>>>              this.cPersistentT = (Class<T>) ((ParameterizedType)
>>> getClass().getGenericSuperclass()).getActualTypeArguments()[0];
>>>      }
>>>
>>>      @SuppressWarnings("unused")
>>>      @PostConstruct
>>>      private void postConstruct() {
>>>              setEntityManagerFactory(emf);
>>>      }
>>>
>>>      @Transactional(propagation = Propagation.REQUIRED)
>>>      public void delete(final T oEntity2Remove) {
>>>              getJpaTemplate().remove(oEntity2Remove);
>>>              flush();
>>>      }
>>>
>>>      @Transactional
>>>      public void delete(final PK oID) {
>>>              T instanceToRemove = getJpaTemplate().find(cPersistentT,
>>> oID);
>>>              getJpaTemplate().remove(instanceToRemove);
>>>              flush();
>>>      }
>>>
>>>      @SuppressWarnings("unchecked")
>>>      public List<T> findAll() {
>>>              return getJpaTemplate().find("select objects from " +
>>> cPersistentT.getSimpleName() + " objects");
>>>      }
>>>
>>>      public T findById(PK oID) {
>>>              return getJpaTemplate().find(getPersistentClass(), oID);
>>>      }
>>>
>>>      @Transactional(propagation = Propagation.REQUIRED)
>>>      public void flush() {
>>>              getJpaTemplate().flush();
>>>      }
>>>
>>>      public Class<T> getPersistentClass() {
>>>              return cPersistentT;
>>>      }
>>>
>>>      @Transactional(propagation = Propagation.REQUIRED)
>>>      public T save(T oInstance) {
>>>              T oReturn = getJpaTemplate().merge(oInstance);
>>>              flush();
>>>              return oReturn;
>>>      }
>>> }
>>>
>>> @Repository
>>> public class ExampleDaoImpl extends GenericDaoJPAImpl<Example, Long>
>>> implements I ExampleDao {
>>>
>>>      public ExampleDaoImpl() {
>>>              super(Example.class);
>>>      }
>>> }
>>>
>>> On 26-09-2008, at 11:48, Tim Hollosy wrote:
>>>
>>>> Thanks Shaun,
>>>> I've completely given up on tomcat at this point, I'll be in an OC4J
>>>> environment in production anyway.
>>>>
>>>> The problem I'm running into now  is there are about 4,000 ways to use
>>>> JPA in Spring:
>>>>
>>>> I can get things to work if I use their JpaDaoSupport class, however I
>>>> would prefer a more "pure" method....which just happened to FINALLY
>>>> work as I typed this, that method was using the @PersistenceContext
>>>> annotation to inject an EntityManager.
>>>>
>>>> Unfortunately, now that it works I have no idea why :) I do see now
>>>> that AspectJ is reporting it's doing stuff, so I think my problems
>>>> before might have been with weaving on some level.
>>>>
>>>> I think part of the problems I was dealing with was two-fold: My Lack
>>>> of any real understanding on the Spring Framework and lack of any real
>>>> examples.
>>>>
>>>> Once I take the time now to analyze what's going on I'll try to remedy
>>>> the latter.
>>>>
>>>> If anyone can impart some best practices for using Eclipselink with
>>>> Spring 2.5 I'd be all ears in the mean time.
>>>>
>>>> ./tch
>>>>
>>>>
>>>>
>>>> On Fri, Sep 26, 2008 at 11:24 AM, Shaun Smith <shaun.smith@xxxxxxxxxx>
>>>> wrote:
>>>>>
>>>>> Hi Tim,
>>>>>
>>>>> If you're using Spring with EclipseLink you must copy
>>>>> spring-tomcat-weaver.jar into $CATALINA_HOME/server/lib see the Spring
>>>>> Manual for details.  Tomcat absolutely will not support dynamic weaving
>>>>> in
>>>>> Spring (or anything else for that matter) unless you use a technique
>>>>> like
>>>>> this.  You didn't mention you did this so don't think you did.  Once
>>>>> you
>>>>> have this in place and you've setup your Spring config properly, Spring
>>>>> will
>>>>> do @PersistenceContext injection.  Take a look at the TopLink
>>>>> Essentials
>>>>> JPA
>>>>> version of the Spring PetClinic for an example.
>>>>>
>>>>>  Shaun
>>>>>
>>>>> Tim Hollosy wrote:
>>>>>
>>>>> So no luck em.isOpen returns true.
>>>>>
>>>>> I can't get my friggin AspectJ Weaver to output anything even though I
>>>>> have an aop.xml like this:
>>>>>
>>>>> <!DOCTYPE aspectj PUBLIC
>>>>> "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd";>
>>>>> <aspectj>
>>>>>  <weaver options="-debug -verbose -showWeaveInfo
>>>>>
>>>>>
>>>>> -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler">
>>>>>     <include within="com.redacted.*"/>
>>>>>  </weaver>
>>>>>  <aspects>
>>>>>     <aspect
>>>>>
>>>>>
>>>>> name="org.springframework.transaction.aspectj.AnnotationTransactionAspect"/>
>>>>>  </aspects>
>>>>> </aspectj>
>>>>>
>>>>>
>>>>> BUT, doing some more reading about weaving I see: at
>>>>>
>>>>>
>>>>> http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial#Limitations_to_JPA
>>>>>
>>>>> As Tomcat is not a JEE5 compatible server, there are some limitiations
>>>>> to
>>>>> JPA.
>>>>>
>>>>>  * No dynamic weaving (instrumentation) - static weaving of
>>>>> entities is still available via EclipseLink
>>>>>  * No @EJB injection of a session bean (containing the
>>>>> EntityManager) is available - use the persistence factory and manager
>>>>> directly
>>>>>  * No @PersistenceContext injection of a container managed
>>>>> persistence unit is available - use
>>>>> Persistence.createEntityManagerFactory(JTA_PU_NAME)
>>>>>
>>>>>
>>>>> Does that mean i can't use the @PersistenceContext annotation with
>>>>> EclipseLink in Tomcat 6???
>>>>>
>>>>> I'm confused as to weather Tomcat 6 supports LTW or not, since there
>>>>> are instructions all over for getting it to weave with Spring...
>>>>>
>>>>> I may set up an OC4J Instance and see if I have better luck, but right
>>>>> now I'm confused as all get out.
>>>>>
>>>>> ./tch
>>>>>
>>>>>
>>>>>
>>>>> On Fri, Sep 26, 2008 at 6:58 AM, Tim Hollosy <hollosyt@xxxxxxxxx>
>>>>> wrote:
>>>>>
>>>>>
>>>>> Mohsen,
>>>>> I didn't actually call isOpen, I instead inspected it with the
>>>>> debugger, and noticed the isOpen boolean was true. I'll try your
>>>>> obvious suggestion when I get in to the office this morning.
>>>>>
>>>>> My hunch is something odd is going on with weaving, so I'm going to
>>>>> put some weaving logging in as well.
>>>>>
>>>>>
>>>>> I guess this is just growing pains and it doesn't always help when I
>>>>> choose bleeding edge -- pure annotations & eclipselink for my first
>>>>> foray into Spring -- but I just can't stand XML, so I've made my bed
>>>>> :)
>>>>>
>>>>> Thanks
>>>>>
>>>>> ./tch
>>>>>
>>>>>
>>>>>
>>>>> On Fri, Sep 26, 2008 at 6:54 AM, Mohsen Saboorian <mohsens@xxxxxxxxx>
>>>>> wrote:
>>>>>
>>>>>
>>>>> I didn't test it with EclipseLink, but with Hibernate session is
>>>>> closed after transaction is committed, and it produces a lot of
>>>>> frustrations with lazy loading, since you usually need to fetch a list
>>>>> after a transaction is committed.
>>>>>
>>>>> Spring provides a OpenSessionInViewFilter to work around this. It
>>>>> keeps session open durig a request life-cycle.
>>>>>
>>>>> How did you verified that EM is open? EM.isOpen()?
>>>>>
>>>>> Mohsen.
>>>>>
>>>>> On Thu, Sep 25, 2008 at 9:58 PM, Tim Hollosy <hollosyt@xxxxxxxxx>
>>>>> wrote:
>>>>>
>>>>>
>>>>> I'm hoping some Spring gurus can help me out, whenever I try to
>>>>> execute a query I get the error: Attempting to execute an operation on
>>>>> a closed EntityManager.
>>>>>
>>>>> I'm using Spring 2.5 + Tomcat6.
>>>>>
>>>>> The weird thing is find's work fine. I'm launching tomcat with the
>>>>> spring-aspects.jar for weaving. I'm new to this whole spring web stuff
>>>>> so I am probably missing something, but the only thing I could find
>>>>> online was to make sure I have the @Transactional annotations used
>>>>> everywhere in my DAO class, which I do.
>>>>>
>>>>> If I run in the debugger it looks like the EM is open as well, so I'm
>>>>> kind of stumped. I suspect some weaving shenanigans, but I'm too much
>>>>> of a neophyte at this right now to debug much more.
>>>>>
>>>>> Many thanks :)
>>>>>
>>>>> Here's my config:
>>>>>
>>>>> applicationcontext.xml;
>>>>> <context:component-scan base-package="com.redacted" />
>>>>>
>>>>>    <tx:annotation-driven mode="aspectj"/>
>>>>>
>>>>> <bean id="transactionManager"
>>>>> class="org.springframework.orm.jpa.JpaTransactionManager"
>>>>>      p:entityManagerFactory-ref="entityManagerFactory"/>
>>>>>
>>>>>    <bean id="dataSource"
>>>>>            class="org.apache.commons.dbcp.BasicDataSource">
>>>>>            <property name="driverClassName"
>>>>> value="oracle.jdbc.OracleDriver" />
>>>>>            <property name="url"
>>>>> value="jdbc:oracle:thin:@redacted:1521:redacted" />
>>>>>            <property name="username" value="redacted" />
>>>>>            <property name="password" value="redacted" />
>>>>>    </bean>
>>>>>
>>>>>    <bean id="jpaAdapter"
>>>>> class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
>>>>> <property name="databasePlatform"
>>>>> value="org.eclipse.persistence.platform.database.oracle.OraclePlatform"
>>>>> />
>>>>> <property name="showSql" value="true" />
>>>>> </bean>
>>>>>
>>>>>
>>>>> <bean id="loadTimeWeaver"
>>>>>
>>>>>
>>>>> class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
>>>>>
>>>>> <bean id="entityManagerFactory"
>>>>>
>>>>>
>>>>> class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
>>>>>   <property name="persistenceUnitName" value="ProofOConcept"/>
>>>>>   <property name="dataSource" ref="dataSource"/>
>>>>>   <property name="jpaVendorAdapter" ref="jpaAdapter"/>
>>>>>   <property name="loadTimeWeaver" ref="loadTimeWeaver"/>
>>>>>
>>>>> </bean>
>>>>>
>>>>>    <util:list id="annotatedClasses">
>>>>>            <value>com.redacted.*</value>
>>>>>    </util:list>
>>>>>
>>>>>
>>>>> Here's my DAO class:
>>>>>
>>>>> import java.util.List;
>>>>>
>>>>> import javax.persistence.EntityManager;
>>>>> import javax.persistence.PersistenceContext;
>>>>> import javax.persistence.Query;
>>>>>
>>>>> import org.eclipse.persistence.jpa.JpaEntityManager;
>>>>> import org.eclipse.persistence.jpa.JpaHelper;
>>>>> import org.springframework.stereotype.Repository;
>>>>> import org.springframework.transaction.annotation.Transactional;
>>>>>
>>>>> @Transactional
>>>>> @Repository
>>>>> public class BasicDao {
>>>>>
>>>>>    @PersistenceContext(unitName = "ProofOConcept")
>>>>>    private EntityManager em;
>>>>>
>>>>>    @Transactional(readOnly = true)
>>>>>    public <T> T find(Class<T> entityClass, Object primaryKey) {
>>>>>            T result = em.find(entityClass, primaryKey);
>>>>>
>>>>>            return result;
>>>>>    }
>>>>>
>>>>>
>>>>>
>>>>>    @Transactional(readOnly = true)
>>>>>    public <T> List<T> selectAll(Class<T> clazz) {
>>>>>            JpaEntityManager jpaEm = JpaHelper.getEntityManager(em);
>>>>>            Query query = jpaEm.createQuery(null, clazz);
>>>>>            return (List<T>) query.getResultList();
>>>>>    }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> ./tch
>>>>> _______________________________________________
>>>>> eclipselink-users mailing list
>>>>> eclipselink-users@xxxxxxxxxxx
>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> eclipselink-users mailing list
>>>>> eclipselink-users@xxxxxxxxxxx
>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> eclipselink-users mailing list
>>>>> eclipselink-users@xxxxxxxxxxx
>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>>
>>>>>
>>>>> --
>>>>>
>>>>>
>>>>>
>>>>> Shaun Smith | Principal Product Manager, TopLink | +1.905.502.3094
>>>>> Oracle Fusion Middleware
>>>>> 110 Matheson Boulevard West, Suite 100
>>>>> Mississauga, Ontario, Canada L5R 3P4
>>>>>
>>>>> _______________________________________________
>>>>> eclipselink-users mailing list
>>>>> eclipselink-users@xxxxxxxxxxx
>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>>
>>>>>
>>>> _______________________________________________
>>>> eclipselink-users mailing list
>>>> eclipselink-users@xxxxxxxxxxx
>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>
>>> _______________________________________________
>>> eclipselink-users mailing list
>>> eclipselink-users@xxxxxxxxxxx
>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>
>> _______________________________________________
>> eclipselink-users mailing list
>> eclipselink-users@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>


Back to the top