java - Spring : 2 EntityManagerFactory in 1 transaction -
i'd access 2 databases in same application. each database connection, have entitymanagerfactory.
problem : can't merge 2 entity in 2 databases in same transaction.
there beans.xml file :
<context:component-scan base-package="com.example.testdatabase.business" /> <context:component-scan base-package="com.example.testdatabase.service" /> <context:component-scan base-package="com.example.testdatabase.ui" /> <bean id="entitymanagerfactoryorder" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <property name="datasource" ref="datasourceorder" /> <property name="packagestoscan" value="com.example.testdatabase.business.order" /> <property name="jpavendoradapter"> <bean class="org.springframework.orm.jpa.vendor.hibernatejpavendoradapter" /> </property> <property name="jpaproperties"> <props> <prop key="hibernate.hbm2ddl.auto">validate</prop> <prop key="hibernate.dialect">org.hibernate.dialect.postgresqldialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="validationquery">select 1 dual</prop> <prop key="testonborrow">true</prop> </props> </property> <property name="persistenceunitname" value="orderpu" /> </bean> <bean id="datasourceorder" class="org.springframework.jndi.jndiobjectfactorybean"> <property name="jndiname" value="java:jboss/datasources/ordercita" /> </bean> <bean id="transactionmanagerorder" class="org.springframework.orm.jpa.jpatransactionmanager"> <property name="entitymanagerfactory" ref="entitymanagerfactoryorder" /> <property name="jpadialect"> <bean class="org.springframework.orm.jpa.vendor.hibernatejpadialect" /> </property> </bean> <bean id="entitymanagerfactoryperson" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <property name="datasource" ref="datasourceperson" /> <property name="packagestoscan" value="com.example.testdatabase.business.person" /> <property name="jpavendoradapter"> <bean class="org.springframework.orm.jpa.vendor.hibernatejpavendoradapter" /> </property> <property name="jpaproperties"> <props> <prop key="hibernate.hbm2ddl.auto">create</prop> <prop key="hibernate.dialect">org.hibernate.dialect.postgresqldialect</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="persistenceunitname" value="personpu" /> </bean> <bean id="datasourceperson" class="org.springframework.jndi.jndiobjectfactorybean"> <property name="jndiname" value="java:jboss/datasources/person" /> </bean> <bean id="transactionmanagerperson" class="org.springframework.orm.jpa.jpatransactionmanager"> <property name="entitymanagerfactory" ref="entitymanagerfactoryperson" /> <property name="jpadialect"> <bean class="org.springframework.orm.jpa.vendor.hibernatejpadialect" /> </property> </bean> <tx:annotation-driven/>
my repository :
@repository public class repo { @persistencecontext(unitname="orderpu") @qualifier(value="entitymanagerfactoryorder") protected entitymanager emorder; @persistencecontext(unitname="personpu") @qualifier(value="entitymanagerfactoryperson") protected entitymanager emperson; public void save() { order o = new order(); o.setthestring("the order"); emorder.merge(o); emorder.close(); person p = new person(); p.setthestring("the person"); emperson.merge(p); emperson.close(); } }
my service :
@service public class manager { @autowired private repo repo; @transactional(value="transactionmanagerorder") public void save1() { repo.save(); } @transactional(value="transactionmanagerperson") public void save2() { repo.save(); } @transactional public void save3() { repo.save(); } }
method "save1()" merge order.
method "save2()" merge person.
merge order , person same transaction.
thanks help
ps : i'm sorry english...
* edit *
tried bitronix have nullpointerexception.
added line in jpaproperties :
org.hibernate.engine.transaction.jta.platform.internal.bitronixjtaplatform
here new beans.xml file :
<bean class="bitronix.tm.transactionmanagerservices" factory-method="getconfiguration" id="bitronixconfiguration" /> <bean class="bitronix.tm.transactionmanagerservices" depends-on="bitronixconfiguration" destroy-method="shutdown" factory-method="gettransactionmanager" id="bitronixtransactionmanager" /> <bean class="bitronix.tm.resource.jdbc.poolingdatasource" destroy-method="close" id="datasourceorder" init-method="init"> <property name="allowlocaltransactions" value="true" /> <property name="classname" value="org.postgresql.xa.pgxadatasource" /> <property name="driverproperties"> <props> <prop key="password">pwd</prop> <prop key="url">jdbc:postgresql://localhost:5432/order</prop> <prop key="user">user</prop> </props> </property> <property name="maxpoolsize" value="5" /> <property name="minpoolsize" value="1" /> <property name="uniquename" value="exampleds" /> </bean> <bean class="bitronix.tm.resource.jdbc.poolingdatasource" destroy-method="close" id="datasourceperson" init-method="init"> <property name="allowlocaltransactions" value="true" /> <property name="classname" value="org.postgresql.xa.pgxadatasource" /> <property name="driverproperties"> <props> <prop key="password">pwd</prop> <prop key="url">jdbc:postgresql://localhost:5432/person</prop> <prop key="user">user</prop> </props> </property> <property name="maxpoolsize" value="5" /> <property name="minpoolsize" value="1" /> <property name="uniquename" value="sampleds" /> </bean> <bean id="entitymanagerfactoryorder" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <property name="jtadatasource" ref="datasourceorder" /> <property name="packagestoscan" value="com.example.testdatabase.business.order" /> <property name="jpavendoradapter"> <bean class="org.springframework.orm.jpa.vendor.hibernatejpavendoradapter" /> </property> <property name="jpaproperties"> <props> <prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.bitronixjtaplatform</prop> <prop key="hibernate.hbm2ddl.auto">validate</prop> <prop key="hibernate.dialect">org.hibernate.dialect.postgresqldialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="validationquery">select 1 dual</prop> <prop key="testonborrow">true</prop> </props> </property> <property name="persistenceunitname" value="orderpu" /> </bean> <bean id="entitymanagerfactoryperson" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <property name="jtadatasource" ref="datasourceperson" /> <property name="packagestoscan" value="com.example.testdatabase.business.person" /> <property name="jpavendoradapter"> <bean class="org.springframework.orm.jpa.vendor.hibernatejpavendoradapter" /> </property> <property name="jpaproperties"> <props> <prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.bitronixjtaplatform</prop> <prop key="hibernate.hbm2ddl.auto">create</prop> <prop key="hibernate.dialect">org.hibernate.dialect.postgresqldialect</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="persistenceunitname" value="personpu" /> </bean> <bean class="org.springframework.transaction.jta.jtatransactionmanager" id="transactionmanager"> <property name="transactionmanager" ref="bitronixtransactionmanager" /> <property name="usertransaction" ref="bitronixtransactionmanager" /> </bean> <tx:annotation-driven />
in manager class, removed @transactional annotation.
in repo class, removed @qualifier annotation.
the stack trace :
00:47:22,665 severe [com.vaadin.server.defaulterrorhandler] (http-localhost/127.0.0.1:8080-2) : java.lang.nullpointerexception @ org.hibernate.engine.transaction.internal.jta.cmttransactionfactory.isjoinablejtatransaction(cmttransactionfactory.java:63) [hibernate-core-4.1.9.final.jar:4.1.9.final] @ org.hibernate.engine.transaction.internal.jta.cmttransactionfactory.isjoinablejtatransaction(cmttransactionfactory.java:39) [hibernate-core-4.1.9.final.jar:4.1.9.final] @ org.hibernate.engine.transaction.internal.transactioncoordinatorimpl.istransactionjoinable(transactioncoordinatorimpl.java:295) [hibernate-core-4.1.9.final.jar:4.1.9.final] @ org.hibernate.ejb.abstractentitymanagerimpl.jointransaction(abstractentitymanagerimpl.java:1205) [hibernate-entitymanager-4.1.9.final.jar:4.1.9.final] @ org.hibernate.ejb.abstractentitymanagerimpl.postinit(abstractentitymanagerimpl.java:178) [hibernate-entitymanager-4.1.9.final.jar:4.1.9.final] @ org.hibernate.ejb.entitymanagerimpl.<init>(entitymanagerimpl.java:89) [hibernate-entitymanager-4.1.9.final.jar:4.1.9.final] @ org.hibernate.ejb.entitymanagerfactoryimpl.createentitymanager(entitymanagerfactoryimpl.java:179) [hibernate-entitymanager-4.1.9.final.jar:4.1.9.final] @ org.hibernate.ejb.entitymanagerfactoryimpl.createentitymanager(entitymanagerfactoryimpl.java:174) [hibernate-entitymanager-4.1.9.final.jar:4.1.9.final] @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) [rt.jar:1.6.0_45] @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) [rt.jar:1.6.0_45] @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) [rt.jar:1.6.0_45] @ java.lang.reflect.method.invoke(method.java:597) [rt.jar:1.6.0_45] @ org.springframework.orm.jpa.abstractentitymanagerfactorybean.invokeproxymethod(abstractentitymanagerfactorybean.java:376) [spring-orm-3.2.5.release.jar:3.2.5.release] @ org.springframework.orm.jpa.abstractentitymanagerfactorybean$managedentitymanagerfactoryinvocationhandler.invoke(abstractentitymanagerfactorybean.java:519) [spring-orm-3.2.5.release.jar:3.2.5.release] @ com.sun.proxy.$proxy38.createentitymanager(unknown source) @ org.springframework.orm.jpa.entitymanagerfactoryutils.dogettransactionalentitymanager(entitymanagerfactoryutils.java:202) [spring-orm-3.2.5.release.jar:3.2.5.release] @ org.springframework.orm.jpa.sharedentitymanagercreator$sharedentitymanagerinvocationhandler.invoke(sharedentitymanagercreator.java:211) [spring-orm-3.2.5.release.jar:3.2.5.release] @ com.sun.proxy.$proxy40.merge(unknown source) @ com.example.testdatabase.business.repo.repo.save(repo.java:29) [classes:] @ com.example.testdatabase.service.manager.save3(manager.java:26) [classes:] @ com.example.testdatabase.service.manager$$fastclassbyspringcglib$$3df77bc4.invoke(<generated>) [spring-core-4.1.6.release.jar:] @ org.springframework.cglib.proxy.methodproxy.invoke(methodproxy.java:204) [spring-core-4.1.6.release.jar:4.1.6.release] @ org.springframework.aop.framework.cglibaopproxy$cglibmethodinvocation.invokejoinpoint(cglibaopproxy.java:717) [spring-aop-4.1.6.release.jar:4.1.6.release] @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:157) [spring-aop-4.1.6.release.jar:4.1.6.release] @ org.springframework.transaction.interceptor.transactioninterceptor$1.proceedwithinvocation(transactioninterceptor.java:98) [spring-tx-4.0.5.release.jar:4.0.5.release] @ org.springframework.transaction.interceptor.transactionaspectsupport.invokewithintransaction(transactionaspectsupport.java:262) [spring-tx-4.0.5.release.jar:4.0.5.release] @ org.springframework.transaction.interceptor.transactioninterceptor.invoke(transactioninterceptor.java:95) [spring-tx-4.0.5.release.jar:4.0.5.release] @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179) [spring-aop-4.1.6.release.jar:4.1.6.release] @ org.springframework.aop.framework.cglibaopproxy$dynamicadvisedinterceptor.intercept(cglibaopproxy.java:653) [spring-aop-4.1.6.release.jar:4.1.6.release] @ com.example.testdatabase.service.manager$$enhancerbyspringcglib$$ab725425.save3(<generated>) [spring-core-4.1.6.release.jar:] @ com.example.testdatabase.testdatabaseui$3.buttonclick(testdatabaseui.java:56) [classes:] @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) [rt.jar:1.6.0_45] @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) [rt.jar:1.6.0_45] @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) [rt.jar:1.6.0_45] @ java.lang.reflect.method.invoke(method.java:597) [rt.jar:1.6.0_45] @ com.vaadin.event.listenermethod.receiveevent(listenermethod.java:508) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.event.eventrouter.fireevent(eventrouter.java:198) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.event.eventrouter.fireevent(eventrouter.java:161) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.server.abstractclientconnector.fireevent(abstractclientconnector.java:995) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.ui.button.fireclick(button.java:393) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.ui.button$1.click(button.java:61) [vaadin-server-7.5.0.jar:7.5.0] @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) [rt.jar:1.6.0_45] @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) [rt.jar:1.6.0_45] @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) [rt.jar:1.6.0_45] @ java.lang.reflect.method.invoke(method.java:597) [rt.jar:1.6.0_45] @ com.vaadin.server.serverrpcmanager.applyinvocation(serverrpcmanager.java:158) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.server.serverrpcmanager.applyinvocation(serverrpcmanager.java:118) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.server.communication.serverrpchandler.handleinvocations(serverrpchandler.java:313) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.server.communication.serverrpchandler.handlerpc(serverrpchandler.java:202) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.server.communication.uidlrequesthandler.synchronizedhandlerequest(uidlrequesthandler.java:95) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.server.synchronizedrequesthandler.handlerequest(synchronizedrequesthandler.java:41) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.server.vaadinservice.handlerequest(vaadinservice.java:1408) [vaadin-server-7.5.0.jar:7.5.0] @ com.vaadin.server.vaadinservlet.service(vaadinservlet.java:350) [vaadin-server-7.5.0.jar:7.5.0] @ javax.servlet.http.httpservlet.service(httpservlet.java:847) [jboss-servlet-api_3.0_spec-1.0.2.final-redhat-1.jar:1.0.2.final-redhat-1] @ org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:295) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:214) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.catalina.core.standardwrappervalve.invoke(standardwrappervalve.java:230) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.catalina.core.standardcontextvalve.invoke(standardcontextvalve.java:149) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.jboss.as.jpa.interceptor.webnontxemcloservalve.invoke(webnontxemcloservalve.java:50) [jboss-as-jpa-7.3.0.final-redhat-14.jar:7.3.0.final-redhat-14] @ org.jboss.as.jpa.interceptor.webnontxemcloservalve.invoke(webnontxemcloservalve.java:50) [jboss-as-jpa-7.3.0.final-redhat-14.jar:7.3.0.final-redhat-14] @ org.jboss.as.web.security.securitycontextassociationvalve.invoke(securitycontextassociationvalve.java:169) [jboss-as-web-7.3.0.final-redhat-14.jar:7.3.0.final-redhat-14] @ org.apache.catalina.core.standardhostvalve.invoke(standardhostvalve.java:145) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.catalina.valves.errorreportvalve.invoke(errorreportvalve.java:97) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.catalina.core.standardenginevalve.invoke(standardenginevalve.java:102) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.catalina.connector.coyoteadapter.service(coyoteadapter.java:336) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.coyote.http11.http11processor.process(http11processor.java:856) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.coyote.http11.http11protocol$http11connectionhandler.process(http11protocol.java:653) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ org.apache.tomcat.util.net.jioendpoint$worker.run(jioendpoint.java:920) [jbossweb-7.2.2.final-redhat-1.jar:7.2.2.final-redhat-1] @ java.lang.thread.run(thread.java:662) [rt.jar:1.6.0_45]
you using local transaction managers manage transactions against 1 data store @ time. managing transactions span across multiple data stores, need jta compliant transaction manager.
see this sample app example of using bitronix jta transaction manager 2 entitymanager
s.
Comments
Post a Comment