Announcement Announcement Module
Collapse
No announcement yet.
Spring injection of Transaction not working in a JPA environment with eclipselink... Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring injection of Transaction not working in a JPA environment with eclipselink...

    Hi Spring users,

    Am having an issue with using eclipselink/spring in a non jta environment with spring. Following is my setup . I have a DAO controlled by spring which uses the eclipselink entity manager . I inject the entity manager factory using the PersistenceUnit annotation (I had some issues using the EntityManager injected in a jta environment which is how we run our servers ), so want to inject the EntityManager Factory which according to the JPA spec is ok.. When I try to persist I am getting the following exception

    com.foo.foobar.common.dao.DAOException:
    Exception Description: No transaction is currently active
    at com.foo.foobar.cm.common.dao.eclipselink.EclipseLi nkDAO.updateDataItem(BaseDAO.java:114)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoi npointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.invokeJoinpoint(ReflectiveMethodInvocat ion.java:183)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :150)
    at org.springframework.aop.interceptor.ExposeInvocati onInterceptor.invoke(ExposeInvocationInterceptor.j ava:89)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :172)
    at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy29.updateStatus(Unknown Source)

    Following is my spring config..

    <context:annotation-config />
    <context:component-scan
    base-package="com.foo.foobar.cm.common.dao.eclipselink" />
    <bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerE ntityManagerFactoryBean">
    <property name="persistenceUnitName" value="PersistenceEl" />
    <property name="jpaDialect" ref="eclipseLinkDialect" />
    <property name="persistenceXmlLocation"
    value="classpath:META-INF/persistence-local-eclipse.xml" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.EclipseL inkJpaVendorAdapter">
    <property name="showSql" value="true" />
    <property name="generateDdl" value="false" />
    </bean>
    </property>
    <property name="jpaPropertyMap">
    <map>
    <entry key="eclipselink.jdbc.native-sql" value="false" />
    <entry key="eclipselink.weaving" value="false" />
    <entry key="eclipselink.persistence-context.flush-mode" value="AUTO" />
    <entry key="eclipselink.logging.logger"
    value="org.eclipse.persistence.logging.DefaultSess ionLog" />
    <entry key="eclipselink.logging.level" value="FINE" />
    <entry key="eclipselink.orm.throw.exceptions" value="true" />
    <entry key="eclipselink.logging.exceptions" value="true" />
    </map>
    </property>
    </bean>

    <bean id="eclipseLinkDialect"
    class="org.springframework.orm.jpa.vendor.EclipseL inkJpaDialect" />
    <!-- the transactional advice (what 'happens'; see the <aop:advisor/>
    bean below) -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!-- the transactional semantics... -->
    <tx:attributes>
    <!-- all methods starting with 'get' are read-only -->
    <tx:method name="testGet*" propagation="SUPPORTS"
    read-only="true" />
    <!-- other methods use the default transaction settings (see below) -->
    <tx:method name="*" propagation="REQUIRES_NEW" read-only="false" />
    </tx:attributes>
    </tx:advice>

    <aop:config>
    <aopointcut id="serviceOperation"
    expression="execution(* com.foo.foobar.cm.common.dao.*.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
    </aop:config>

    <bean id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionM anager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <property name="jpaDialect" ref="eclipseLinkDialect" />
    <property name="nestedTransactionAllowed" value="true" />
    </bean>



    persistence file is as follows

    <?xml version="1.0" encoding="UTF-8"?>

    <persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

    <persistence-unit name="MABPersistenceEl" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceP rovider</provider>
    <non-jta-data-source>pmabDataSource</non-jta-data-source>

    // bunch of classes ommited here for brevity

    <exclude-unlisted-classes />
    </persistence-unit>
    </persistence>




    my test is as follows

    @Test
    @Transactional(propagation=Propagation.REQUIRES_NE W)
    @Rollback(false)
    public void testReferenceDataItems()
    {
    // Get inStatus and populate it .. dont set the id.
    someStatus = (Foo) myDAO.updateStatus(inStatus);
    }


    and in myDAO i have the following code

    public abstract BaseDAO
    {

    @PersistenceUnit(unitName="PersistenceEl")
    private EntityManagerFactory entityManagerFactory;

    public SomeStatus updateDataItem(SomeStatus inStatus)
    {
    EntityManager em=entityManagerFactory.createEntityManager();
    //check for id,, assume null (not shown for brevity)
    em.persist(inStatus);
    em.flush(); // it craps out here..
    SomeStatus t1= (T)emgr.find(SomeStatus.class,inStatus.getId()); //
    return t1;
    }
    }



    When I had a similiar issue in hibernate (we are involving in converting from hibernate to eclipselink , fyi) , we used the following extra property in the jpa property map
    <entry key="hibernate.current_session_context_class"
    value="org.springframework.orm.hibernate3.SpringSe ssionContext" /> and it started working.Also when checking in eclipselink documentation looks like i dont need to set this..

    Can some one please help me.. ? We are totally struck because of this issue .Is there a wrong configuration that anyone can spot.. This seems to be very basic . Has anyone tried this approach . When we tried the
    entity Manager it works in the above set up , but it is not working in a jta setup as the Spring Shared EntityManager Creator creates a new entity manager everytime, so we would like to inject the EntityManagerFactory itself...

    Cheers
Working...
X