Hi,
I'm porting an app from iBatis 2.3.4 to MyBatis 3.1.1 and have run in
the following problem.
In my service-project I have a method as follows:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public Vet storeVet(Vet vet, DataSourceType dataSourceType,
JopoContext jopoContext) {
return manageClinicFacade.storeVet(vet, dataSourceType,
jopoContext);
}
In iBatis this worked just fine without any explicit transaction
managers in the Spring context. But when using MyBatis 3.1.1 and
MyBatis-Spring 1.1.1 I get the following error:
java.sql.SQLException: Cannot call Connection.commit in distributed
transaction. Transaction Manager will commit the resource manager
when the distributed transaction is committed.
at weblogic.jdbc.wrapper.JTSConnection.commit(JTSConnection.java:615)
at
org.mybatis.spring.transaction.SpringManagedTransaction.commit(SpringManagedTransaction.java:
102)
at org.apache.ibatis.executor.BaseExecutor.commit(BaseExecutor.java:
203)
at
org.apache.ibatis.executor.CachingExecutor.commit(CachingExecutor.java:
113)
at
org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:
167)
at org.mybatis.spring.SqlSessionTemplate
$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:359)
at $Proxy199.insert(Unknown Source)
at
org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:
237)
at
fi.op.jopo.persistence.mybatis.AbstractMapperRepository.insert(AbstractMapperRepository.java:
150)
at
fi.op.silta3.manageclinic.persistence.VetRepositoryImpl.storeVet(VetRepositoryImpl.java:
116)
at
fi.op.silta3.manageclinic.service.facade.ManageClinicFacadeImpl.storeVet(ManageClinicFacadeImpl.java:
167)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:
318)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:
183)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
150)
at
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:
50)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
161)
at
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:
50)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
161)
at
org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:
55)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
161)
at
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:
90)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
172)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:
202)
at $Proxy200.storeVet(Unknown Source)
at
fi.op.silta3.manageclinic.service.ManageClinicServiceEJB.storeVet(ManageClinicServiceEJB.java:
106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:
310)
at
com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:
182)
at
com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
149)
at
com.bea.core.repackaged.springframework.jee.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:
104)
at
com.bea.core.repackaged.springframework.jee.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:
72)
at
com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
171)
at
com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:
131)
at
com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:
119)
at
com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
171)
at
com.bea.core.repackaged.springframework.jee.spi.MethodInvocationVisitorImpl.visit(MethodInvocationVisitorImpl.java:
37)
at
weblogic.ejb.container.injection.EnvironmentInterceptorCallbackImpl.callback(EnvironmentInterceptorCallbackImpl.java:
54)
at
com.bea.core.repackaged.springframework.jee.spi.EnvironmentInterceptor.invoke(EnvironmentInterceptor.java:
50)
at
com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
171)
at
com.bea.core.repackaged.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:
89)
at
com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
171)
at
com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:
131)
at
com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:
119)
at
com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
171)
at
com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:
204)
at $Proxy186.storeVet(Unknown Source)
at
fi.op.silta3.manageclinic.service.ManageClinicServiceEJB_c80ui2_ManageClinicServiceImpl.storeVet(ManageClinicServiceEJB_c80ui2_ManageClinicServiceImpl.java:
187)
at
fi.op.silta3.manageclinic.service.ManageClinicServiceEJB_c80ui2_ManageClinicServiceImpl_WLSkel.invoke(Unknown
Source)
at weblogic.rmi.internal.ServerRequest.sendReceive(ServerRequest.java:
174)
at
weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:
345)
at
weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:
259)
at
fi.op.silta3.manageclinic.service.ManageClinicServiceEJB_c80ui2_ManageClinicServiceImpl_1033_WLStub.storeVet(Unknown
Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:
84)
at $Proxy171.storeVet(Unknown Source)
at
fi.op.silta3.manageclinic.service.ManageClinicServiceEJBDelegate.storeVet(ManageClinicServiceEJBDelegate.java:
52)
at
fi.op.silta3.petclinic.service.facade.PetclinicFacadeImpl.storeVet(PetclinicFacadeImpl.java:
324)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:
318)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:
183)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
150)
at
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:
50)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
161)
at
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:
50)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
161)
at
org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:
55)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
161)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:
110)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
172)
at
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:
90)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
172)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:
202)
at $Proxy112.storeVet(Unknown Source)
at
fi.op.silta3.petclinic.web.controller.VetController.processAddVetForm(VetController.java:
139)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:
213)
at
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:
126)
at
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:
96)
at
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:
617)
at
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:
578)
at
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:
80)
at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:
923)
at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:
852)
at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:
882)
at
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:
789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper
$ServletServiceAction.run(StubSecurityHelper.java:227)
at
weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:
125)
at
weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:
300)
at
weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:
183)
at weblogic.servlet.internal.WebAppServletContext
$ServletInvocationAction.doIt(WebAppServletContext.java:3686)
at weblogic.servlet.internal.WebAppServletContext
$ServletInvocationAction.run(WebAppServletContext.java:3650)
at
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:
321)
at
weblogic.security.service.SecurityManager.runAs(SecurityManager.java:
121)
at
weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:
2268)
at
weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:
2174)
at
weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:
1446)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
In the Mybatis-Spring documentation it states that:
Note that if you want to use CMT and do not want to use Spring
transaction management, you must not
configure any Spring transaction manager and you must also configure
the SqlSessionFactoryBean to use the
base MyBatis ManagedTransactionFactory:
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionFactory">
<bean
class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" /
>
</property>
</bean>
As this is the case, I tried this and on the surface it seems to work,
but the logging reveals the truth:
---> 05.06.2012 11:30:37.959 [DEBUG]
org.mybatis.spring.SqlSessionUtils#debug[tId=16, deviceId=SILTA, osuva-
session-id=KEHIU551267:10.132.41.148, representable=599950,
transaction-bank=null, transaction-branch=null, message=Creating a new
SqlSession]
---> 05.06.2012 11:30:37.959 [DEBUG]
org.mybatis.spring.SqlSessionUtils#debug[tId=16, deviceId=SILTA, osuva-
session-id=KEHIU551267:10.132.41.148, representable=599950,
transaction-bank=null, transaction-branch=null, message=SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@1360f55] was not
registered for synchronization because synchronization is not active]
---> 05.06.2012 11:30:37.959 [DEBUG] Vet.insertVet!
selectKey#debug[tId=16, deviceId=SILTA, osuva-session-
id=KEHIU551267:10.132.41.148, representable=599950, transaction-
bank=null, transaction-branch=null, message=ooo Using Connection
[weblogic.jdbc.wrapper.JTSConnection_com_ibm_db2_jcc_t4_b@74]]
---> 05.06.2012 11:30:37.959 [DEBUG] Vet.insertVet!
selectKey#debug[tId=16, deviceId=SILTA, osuva-session-
id=KEHIU551267:10.132.41.148, representable=599950, transaction-
bank=null, transaction-branch=null, message===> Preparing: SELECT
NEXT VALUE FOR PET.QVETS FROM SYSIBM.SYSDUMMY1 ]
---> 05.06.2012 11:30:37.959 [DEBUG] Vet.insertVet!
selectKey#debug[tId=16, deviceId=SILTA, osuva-session-
id=KEHIU551267:10.132.41.148, representable=599950, transaction-
bank=null, transaction-branch=null, message===> Parameters: ]
---> 05.06.2012 11:30:37.959 [DEBUG] Vet.insertVet#debug[tId=16,
deviceId=SILTA, osuva-session-id=KEHIU551267:10.132.41.148,
representable=599950, transaction-bank=null, transaction-branch=null,
message=ooo Using Connection
[weblogic.jdbc.wrapper.JTSConnection_com_ibm_db2_jcc_t4_b@74]]
---> 05.06.2012 11:30:37.959 [DEBUG] Vet.insertVet#debug[tId=16,
deviceId=SILTA, osuva-session-id=KEHIU551267:10.132.41.148,
representable=599950, transaction-bank=null, transaction-branch=null,
message===> Preparing: insert into PET.TVETS (VET_ID, VET_VERSION,
VET_FIRST_NAME, VET_LAST_NAME) values (?, 1, ?, ?) ]
---> 05.06.2012 11:30:37.959 [DEBUG] Vet.insertVet#debug[tId=16,
deviceId=SILTA, osuva-session-id=KEHIU551267:10.132.41.148,
representable=599950, transaction-bank=null, transaction-branch=null,
message===> Parameters: 13(Long), Pauli(String), Puoskari(String)]
---> 05.06.2012 11:30:37.974 [DEBUG]
org.mybatis.spring.SqlSessionUtils#debug[tId=16, deviceId=SILTA, osuva-
session-id=KEHIU551267:10.132.41.148, representable=599950,
transaction-bank=null, transaction-branch=null, message=Closing non
transactional SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@1360f55]]
The method does not participate in the distributed transaction! I
looked through previous posts in the mailing list and found this post
(
http://groups.google.com/group/mybatis-user/browse_thread/thread/
fb53974e69cc021/aef5ff7d47592e00?
lnk=gst&q=ManagedTransactionFactory#aef5ff7d47592e00) that had the
same problem as I do and on the surface it seems to work but the
following post (
http://groups.google.com/group/mybatis-user/
browse_thread/thread/fb53974e69cc021/5b1634aa383ac283?
lnk=gst&q=ManagedTransactionFactory#5b1634aa383ac283) in the thread
comes to the same conclusion that there is a problem/bug with the
documented solution.
Sorry for the lengthy post, but does anybody know if there is really a
bug or am I missing something? I even tried the other route by
configuring this (<tx:jta-transaction-manager />) but that obviously
does not work as Spring does not manage the transactions.
Thanks in advance!
-Kari