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.

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
>


Back to the top