java - How to insert into database when using JTA + JPA with Spring -
i have simple web application using jta + jpa along spring (version 4). doing xa transaction using atomikos jta transaction manager. transaction involves inserting employeea entity databasea , employeeb entity databaseb.
strangely, application not throw error but no enteries inserted databases.
public class jtatest { public static void main( string[] args ) { jtatest test = new jtatest(); test.testmandatory(); } private static void testmandatory() { final springcontextutil util = springcontextutil.instance(); applicationcontext ctx = util.getapplicationcontext(); final jtaemployeeservice employeeservice = (jtaemployeeservice)ctx.getbean("jtaemployeeservice"); employeea = new employeea(); a.setname("emp-a-1"); a.setage(30); employeeb b = new employeeb(); a.setname("emp-b-1"); a.setage(31); try { employeeservice.persistemployees(a, b); } catch (exception e) { e.printstacktrace(); } system.out.println("success"); } }
the service class implementation:
@service("jtaemployeeservice") public class jtaemployeeserviceimpl implements jtaemployeeservice { @autowired @qualifier("employeea") private genericdao<integer, employeea> employeeadao; @autowired @qualifier("employeeb") private genericdao<integer, employeeb> employeebdao; @override @transactional( propagation=propagation.required, readonly=false, isolation=isolation.default, rollbackfor=exception.class) public void persistemployees(employeea employeea, employeeb employeeb) throws exception { employeeadao.save(employeea); employeebdao.save(employeeb); system.out.println("saving employee , employee b "); } }
the dao implementation , interfaces:
@repository("employeeb") public class employeebdaoimpl extends abstractjtadaodatabaseb implements genericdao<integer, employeeb> { @override public void save(employeeb entity) { super.persist(entity); } } @repository("employeea") public class employeeadaoimpl extends abstractjtadaodatabasea implements genericdao<integer, employeea> { @override public void save(employeea entity) { super.persist(entity); } } public abstract class abstractjtadaodatabaseb { @persistencecontext(unitname = "persistenceunitb") @qualifier("mymanager") private entitymanager entitymanager; public void persist(object entity) { entitymanager.persist(entity); // entitymanager.flush(); } protected entitymanager getentitymanager() { return entitymanager; } } public abstract class abstractjtadaodatabasea { @persistencecontext(unitname = "persistenceunita") @qualifier("mymanager") private entitymanager entitymanager; public void persist(object entity) { entitymanager.persist(entity); // entitymanager.flush(); } protected entitymanager getentitymanager() { return entitymanager; } }
servlet-context.xml
<?xml version="1.0" encoding="utf-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- dispatcherservlet context: defines servlet's request-processing infrastructure --> <!-- enables spring mvc @controller programming model --> <annotation-driven /> <!-- enables annotaion driven transactional support on springs --> <!-- <tx:annotation-driven transaction-manager="htransactionmanager"/> --> <!-- <tx:jta-transaction-manager transaction-manager="jtatransactionmanager"/> --> <tx:annotation-driven transaction-manager="jtatransactionmanager"/> <!-- list packages annotated springs annotaions @controller, @repository, @service, @component --> <context:component-scan base-package="com.goraksh.spring.tutorial.controller.business, com.goraksh.spring.tutorial.controller.rest, com.goraksh.spring.tutorial.service, com.goraksh.spring.tutorial.dao" /> <beans:bean class="org.springframework.web.servlet.view.internalresourceviewresolver"> <beans:property name="prefix" value="/web-inf/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> <beans:bean class="org.springframework.beans.factory.config.propertyplaceholderconfigurer"> <beans:property name="location" value="classpath:application.properties"/> </beans:bean> <!-- <beans:bean id="sessionfactory" class="org.springframework.orm.hibernate4.annotation.annotationsessionfactorybean"> --> <beans:bean id="sessionfactory" class="org.springframework.orm.hibernate4.localsessionfactorybean"> <beans:property name="datasource" ref="datasource" /> <beans:property name="hibernateproperties"> <beans:props> <beans:prop key="hibernate.dialect">org.hibernate.dialect.sqlserverdialect</beans:prop> <!-- <beans:prop key="hibernate.current_session_context_class">thread</beans:prop> --> <beans:prop key="hibernate.show_sql">${hibernate.show_sql}</beans:prop> <beans:prop key="hibernate.format_sql">${hibernate.format_sql}</beans:prop> <beans:prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</beans:prop> <beans:prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</beans:prop> <beans:prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</beans:prop> <beans:prop key="net.sf.ehcache.configurationresourcename">${net.sf.ehcache.configurationresourcename}</beans:prop> </beans:props> </beans:property> <!--<beans:property name="annotatedclasses"> --> <!-- packagestoscan meant give package javax.persistence.entity classes stored , recognised via annotations--> <beans:property name="packagestoscan"> <beans:list> <beans:value>com.goraksh.spring.tutorial.model</beans:value> </beans:list> </beans:property> </beans:bean> <beans:bean id="datasource" class="org.springframework.jdbc.datasource.drivermanagerdatasource"> <beans:property name="driverclassname" value="${jdbc.driverclassname}"/> <beans:property name="url" value="${jdbc.url}"/> <beans:property name="username" value="${jdbc.username}"/> <beans:property name="password" value="${jdbc.password}"/> </beans:bean> <beans:bean id = "htransactionmanager" class = "org.springframework.orm.hibernate4.hibernatetransactionmanager"> <beans:property name = "sessionfactory" ref = "sessionfactory" /> </beans:bean> <!-- jata transactions atomikos --> <beans:bean id="datasourcea" class="com.atomikos.jdbc.atomikosdatasourcebean" init-method="init" destroy-method="close"> <beans:property name="uniqueresourcename"><beans:value>datasourcea</beans:value></beans:property> <beans:property name="xadatasourceclassname"><beans:value>com.mysql.jdbc.jdbc2.optional.mysqlxadatasource</beans:value></beans:property> <beans:property name="xaproperties"> <beans:props> <beans:prop key="databasename">traningdb</beans:prop> <beans:prop key="servername">localhost</beans:prop> <beans:prop key="port">3306</beans:prop> <beans:prop key="user">root</beans:prop> <beans:prop key="password">root</beans:prop> <beans:prop key="url">jdbc:mysql://localhost:3306/traningdb</beans:prop> </beans:props> </beans:property> <beans:property name="minpoolsize"><beans:value>1</beans:value></beans:property> </beans:bean> <beans:bean id="datasourceb" class="com.atomikos.jdbc.atomikosdatasourcebean" init-method="init" destroy-method="close"> <beans:property name="uniqueresourcename"><beans:value>datasourceb</beans:value></beans:property> <beans:property name="xadatasourceclassname"><beans:value>com.mysql.jdbc.jdbc2.optional.mysqlxadatasource</beans:value></beans:property> <beans:property name="xaproperties"> <beans:props> <beans:prop key="databasename">traningdb2</beans:prop> <beans:prop key="servername">localhost</beans:prop> <beans:prop key="port">3306</beans:prop> <beans:prop key="user">root</beans:prop> <beans:prop key="password">root</beans:prop> <beans:prop key="url">jdbc:mysql://localhost:3306/traningdb2</beans:prop> </beans:props> </beans:property> <beans:property name="minpoolsize"> <beans:value>1</beans:value> </beans:property> </beans:bean> <beans:bean id="entitymanagerfactorya" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <beans:property name="persistencexmllocation"> <beans:value>classpath:meta-inf/persistence.xml</beans:value> </beans:property> <beans:property name="persistenceunitname" value="persistenceunita" /> <beans:property name="datasource" ref="datasourcea" /> <beans:property name="jpavendoradapter"> <beans:bean class="org.springframework.orm.jpa.vendor.hibernatejpavendoradapter"> <beans:property name="showsql" value="true" /> <beans:property name="databaseplatform" value="org.hibernate.dialect.mysql5innodbdialect" /> </beans:bean> </beans:property> </beans:bean> <beans:bean id="entitymanagerfactoryb" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <beans:property name="persistencexmllocation"> <beans:value>classpath:meta-inf/persistence.xml</beans:value> </beans:property> <beans:property name="persistenceunitname" value="persistenceunitb" /> <beans:property name="datasource" ref="datasourceb" /> <beans:property name="jpavendoradapter"> <beans:bean class="org.springframework.orm.jpa.vendor.hibernatejpavendoradapter"> <beans:property name="showsql" value="true" /> <beans:property name="databaseplatform" value="org.hibernate.dialect.mysql5innodbdialect" /> </beans:bean> </beans:property> </beans:bean> <beans:bean id="atomikostransactionmanager" class="com.atomikos.icatch.jta.usertransactionmanager" init-method="init" destroy-method="close"> <beans:property name="forceshutdown" value="false" /> <!-- <beans:property name="startuptransactionservice" value="false" /> --> </beans:bean> <beans:bean id="atomikosusertransaction" class="com.atomikos.icatch.jta.usertransactionimp"> <beans:property name="transactiontimeout" value="300" /> </beans:bean> <beans:bean id="jtatransactionmanager" class="org.springframework.transaction.jta.jtatransactionmanager" depends-on="atomikostransactionmanager,atomikosusertransaction"> <beans:qualifier value="mymanager"/> <beans:property name="transactionmanager" ref="atomikostransactionmanager" /> <beans:property name="usertransaction" ref="atomikosusertransaction" /> <beans:property name="allowcustomisolationlevels" value="true" /> </beans:bean> </beans:beans>
persistence.xml
<?xml version="1.0" encoding="utf-8"?> <persistence version="2.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_2_0.xsd"> <persistence-unit name="persistenceunita" > <class>com.goraksh.spring.tutorial.model.employeea</class> <exclude-unlisted-classes /> <properties> <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.singletonehcacheregionfactory" /> </properties> </persistence-unit> <persistence-unit name="persistenceunitb" > <class>com.goraksh.spring.tutorial.model.employeeb</class> <exclude-unlisted-classes /> <properties> <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.singletonehcacheregionfactory" /> </properties> </persistence-unit> </persistence>
any highly solicited.
after lot of head-whacking , many hit-and-trial debugging, able solve problem. looks below property required in persistence.xml
hibernate.transaction.jta.platform
on application server there multiple options available different jta paltform services
but since needed 1 standalone jta platform implementation added 1 of own.
com.goraksh.spring.atomikos.jta.platform.atomikosjtaplatform
so here modified persistence.xml:
<?xml version="1.0" encoding="utf-8"?> <persistence version="2.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_2_0.xsd"> <persistence-unit name="persistenceunita" transaction-type="jta" > <class>com.goraksh.spring.tutorial.model.employeea</class> <exclude-unlisted-classes /> <properties> <property name="hibernate.transaction.jta.platform" value="com.goraksh.spring.atomikos.jta.platform.atomikosjtaplatform" /> <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.singletonehcacheregionfactory" /> </properties> </persistence-unit> <persistence-unit name="persistenceunitb" transaction-type="jta"> <class>com.goraksh.spring.tutorial.model.employeeb</class> <exclude-unlisted-classes /> <properties> <property name="hibernate.transaction.jta.platform" value="com.goraksh.spring.atomikos.jta.platform.atomikosjtaplatform" /> <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.singletonehcacheregionfactory" /> </properties> </persistence-unit> </persistence>
the source code com.goraksh.spring.atomikos.jta.platform.atomikosjtaplatform
package com.goraksh.spring.atomikos.jta.platform; import javax.transaction.transactionmanager; import javax.transaction.usertransaction; import org.hibernate.engine.transaction.jta.platform.internal.abstractjtaplatform; import com.atomikos.icatch.jta.usertransactionimp; import com.atomikos.icatch.jta.usertransactionmanager; public final class atomikosjtaplatform extends abstractjtaplatform { private transactionmanager utm = new usertransactionmanager(); private usertransaction usertransaction = new usertransactionimp(); /** * */ private static final long serialversionuid = -74991083213512919l; @override protected transactionmanager locatetransactionmanager() { return utm; } @override protected usertransaction locateusertransaction() { return usertransaction; } }
Comments
Post a Comment