PDA

View Full Version : Using JTA with Spring +hibernate JPA+Glassfish 3.1 Transaction not committing



chinedubond
Mar 6th, 2012, 08:34 AM
I have been struggling with this issues and i have searched the entire internet but to no avail. I am hoping you guy can help me I using glassfish 3.1 with hibernate JPA and spring 3. I have configured a datasource and pool in Glassfish to target MYSQL please find my configurations

the Web.xml , i configured the persistence units.

<persistence-unit-ref>
<description>Persistence Unit for PlyPlus</description>
<persistence-unit-ref-name>
persistence/zeneJPA
</persistence-unit-ref-name>
<persistence-unit-name>
ZeneJPA
</persistence-unit-name>
</persistence-unit-ref>
The application-context

<context:component-scan base-package="com.binarydna.store" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnn otationBeanPostProcessor">
<property name="persistenceUnits">
<map>
<entry key="ZeneJPA" value="persistence/zeneJPA">
</entry>
</map>
</property>
</bean>
<!--
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFact oryBean">
<property name="persistenceUnitName" value="ZeneJPA"/>
</bean>
-->
<!-- We want to use Spring's declarative @Transaction management -->
<tx:annotation-driven />
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/zeneJPA" />
<tx:jta-transaction-manager />
Persistence.xml

<persistence-unit name="ZeneJPA" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/zeneDS</jta-data-source>
<properties>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManager Lookup"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.generate_statistics" value="true"/>
<property name="hibernate.archive.autodetection" value="class,hbm"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
the method/class that saves the object

@Repository("AdminDAO")
@Transactional
public class AdminDAOImpl implements AdminDAO {

@PersistenceContext
private EntityManager em;


public void setEntityManager(EntityManager em) {
this.em = em;
}

@Override
public boolean saveCustomer(Customer customer) {
boolean saved = false;
try {
if (customer.getId() == null) {
this.em.persist(customer);
}
else {
this.em.merge(customer);
}
saved = true;
}
catch (Exception p) {
saved = false;
return saved;
}
return saved;
}
}
Please help me out here what am i doing wrong?? This configuration generates the tables but just does not commit the transaction. When i step through using the degugger it actually calls the save but does not commit the transaction. Please what is the appropraite configuration to get spring transaction working with Glassfish? Thanks I appreciate all the help.

Marten Deinum
Mar 7th, 2012, 01:19 AM
Please use [ code][/code ] tags when posting code, that way it remains readable... For starters when use transaction management from spring NEVER catch the exception this will break proper transaction management (the transaction interceptor doesn't see an exception and thus doesn't rollback but tries to commit).

Next the actual transactional layer should be your service layer and not your daos'

Also please post the code that you use to test this. In your debugging check if there is a TransactionInterceptor somewhere in your call stack.

chinedubond
Mar 8th, 2012, 03:38 AM
hello sir,
Thanks for the reply.
I followed your recommendation and removed the try and catch as well as transferring the @transaction to the service layer.
when i debugging again the data was not committed to the database.
So I added flush() after persist() and I got this exception.
TransactionRequiredException.
No externally managed transaction is currently active for this thread.

what do i do please?
Isn't there like a standard config for spring,JPA+glassfish using JTA?
I appreciate any help.

Marten Deinum
Mar 8th, 2012, 03:44 AM
As I already stated check your call stack if the transaction interceptor is there if it isn't you have a tx setup problem.

Also make sure you don't have a duplicate component-scan (one in your servlet.xml and one in your contextloaderlistener.xml that way you have duplicate instances).

chinedubond
Mar 8th, 2012, 08:11 AM
Thanks a lot . That was it . There were duplication "component-scan" both in the -servlet.xml and *applicationContext.xml.
Everything is working now.
Thanks again.

chinedubond
Mar 12th, 2012, 03:29 PM
thanks a lot for the help Mark.
I ran into another issue while trying to use the applicationContext-jpa in my webflow application.
i imported it into the web-application.xml config.


<import resource="webmvc-config.xml" />
<import resource="webflow-config.xml" />
<import resource="classpath:applicationContext-jpa.xml" />



This is my flow.


<persistence-context />
<var class="com.binarydna.store.domain.Customer" name="userreg" />
<view-state id="initpage" >
<on-render>
<render fragments="body" />
</on-render>
<transition on="next" to="personalInfo" />
</view-state>
<view-state id="personalInfo" model="userreg" >
<on-render>
<render fragments="body" />
</on-render>
</view-state>


</flow>

When I deloy everything is fine but when i try to access my flow
I am getting this error. please help.
Other spring mvc parts of my application works fine

chinedubond
Mar 12th, 2012, 03:40 PM
thanks a lot for the help Mark.
I ran into another issue while trying to use the applicationContext-jpa in my webflow application.
i imported it into the web-application.xml config.


<import resource="webmvc-config.xml" />
<import resource="webflow-config.xml" />
<import resource="classpath:applicationContext-jpa.xml" />



This is my flow.


<persistence-context />
<var class="com.binarydna.store.domain.Customer" name="userreg" />
<view-state id="initpage" >
<on-render>
<render fragments="body" />
</on-render>
<transition on="next" to="personalInfo" />
</view-state>
<view-state id="personalInfo" model="userreg" >
<on-render>
<render fragments="body" />
</on-render>
</view-state>


</flow>

I also config the jpaflow listener in my *flow-config


<bean id="jpaFlowExecutionListener"
class="org.springframework.webflow.persistence.JpaFlowExe cutionListener">
<constructor-arg ref="entityManagerFactory" />
<constructor-arg ref="transactionManager" />
</bean>
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<!-- <webflow:listener ref="securityFlowExecutionListener" />-->
<webflow:listener ref="jpaFlowExecutionListener" />
</webflow:flow-execution-listeners>

</webflow:flow-executor>

When I deloy everything is fine but when i try to access my flow
I am getting this error.


[#|2012-03-12T21:34:41.664+0100|WARNING|glassfish3.1|javax.en terprise.system.container.web.com.sun.enterprise.w eb|_ThreadID=40;_ThreadName=http-thread-pool-8080(4);|StandardWrapperValve[plyplus]: PWC1406: Servlet.service() for servlet plyplus threw exception
java.lang.IllegalStateException: ResourceAdapter not initialized
at com.sun.gjc.spi.ResourceAdapter.getInstance(Resour ceAdapter.java:88)
at com.sun.gjc.spi.ManagedConnectionFactory.readExter nal(ManagedConnectionFactory.java:1458)
at java.io.ObjectInputStream.readExternalData(ObjectI nputStream.java:1810)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1769)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(Object InputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInp utStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputSt ream.java:369)
at java.util.HashMap.readObject(HashMap.java:1043)
at sun.reflect.GeneratedMethodAccessor49.invoke(Unkno wn Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadObject(ObjectS treamClass.java:991)
at java.io.ObjectInputStream.readSerialData(ObjectInp utStream.java:1866)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(Object InputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInp utStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(Object InputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInp utStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(Object InputStream.java:1964)
at java.io.ObjectInputStream.defaultReadObject(Object InputStream.java:498)
at org.hibernate.ejb.AbstractEntityManagerImpl.readOb ject(AbstractEntityManagerImpl.java:1237)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadObject(ObjectS treamClass.java:991)
at java.io.ObjectInputStream.readSerialData(ObjectInp utStream.java:1866)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputSt ream.java:369)
at java.util.HashMap.readObject(HashMap.java:1043)
at sun.reflect.GeneratedMethodAccessor49.invoke(Unkno wn Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadObject(ObjectS treamClass.java:991)
at java.io.ObjectInputStream.readSerialData(ObjectInp utStream.java:1866)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(Object InputStream.java:1964)
at java.io.ObjectInputStream.defaultReadObject(Object InputStream.java:498)
at org.springframework.webflow.core.collection.LocalA ttributeMap.readObject(LocalAttributeMap.java:331)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadObject(ObjectS treamClass.java:991)
at java.io.ObjectInputStream.readSerialData(ObjectInp utStream.java:1866)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1771)

:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputSt ream.java:369)
at org.springframework.webflow.engine.impl.FlowExecut ionImpl.readExternal(FlowExecutionImpl.java:307)
at java.io.ObjectInputStream.readExternalData(ObjectI nputStream.java:1810)
at java.io.ObjectInputStream.readOrdinaryObject(Objec tInputStream.java:1769)
at java.io.ObjectInputStream.readObject0(ObjectInputS tream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputSt ream.java:369)
at org.springframework.webflow.execution.repository.s napshot.SerializedFlowExecutionSnapshot.deserializ e(SerializedFlowExecutionSnapshot.java:194)
at org.springframework.webflow.execution.repository.s napshot.SerializedFlowExecutionSnapshot.unmarshal( SerializedFlowExecutionSnapshot.java:99)
at org.springframework.webflow.execution.repository.s napshot.SerializedFlowExecutionSnapshotFactory.res toreExecution(SerializedFlowExecutionSnapshotFacto ry.java:80)
at org.springframework.webflow.execution.repository.s napshot.AbstractSnapshottingFlowExecutionRepositor y.restoreFlowExecution(AbstractSnapshottingFlowExe cutionRepository.java:89)
at org.springframework.webflow.execution.repository.i mpl.DefaultFlowExecutionRepository.getFlowExecutio n(DefaultFlowExecutionRepository.java:115)
at org.springframework.webflow.executor.FlowExecutorI mpl.resumeExecution(FlowExecutorImpl.java:168)
at org.springframework.webflow.mvc.servlet.FlowHandle rAdapter.handle(FlowHandlerAdapter.java:183)
at org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:900)
at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:827)
at org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:874)
at org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:779)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:735)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:848)
at org.apache.catalina.core.StandardWrapper.service(S tandardWrapper.java:1534)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:343)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:215)
at org.springframework.orm.jpa.support.OpenEntityMana gerInViewFilter.doFilterInternal(OpenEntityManager InViewFilter.java:147)
at org.springframework.web.filter.OncePerRequestFilte r.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:256)


please help.
Other spring mvc parts of my application works fine

Marten Deinum
Mar 13th, 2012, 02:14 AM
Why are you loading the jpa stuff again? It is already loaded by the contextloaderlistener and as such already available to your webflow configuration.

Judging from the stacktrace the problem is the fact that the JNDI based entitymanager(factory) is being serialized. But I don't have a solution ready for that.