Atomikos, Hibernate 4/5, Spring 4, Jetty - unable to locate current JTA transaction - spring

I have tried many different solutions, but getting the exception:
org.hibernate.HibernateException: Unable to locate current JTA transaction
I am using Atomikos, Hibernate 4/5, Spring 4 and Jetty.
How to configure Spring 4 + Hibernate 4/5 (non JPA)?
Atomikos documentation only has an example with JPA.
I would be very grateful for a working example (non JPA, non JEE Application server).
This example changes non JPA:
<context:annotation-config />
<context:component-scan base-package="com.atomikos.icatch.jta.hibernate4" />
<tx:annotation-driven transaction-manager="transactionManager" mode="proxy" proxy-target-class="false" />
<aop:aspectj-autoproxy />
<!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close" depends-on="dataSource">
<property name="forceShutdown" value="true" />
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<!-- by default : looks for java:comp/UserTransaction -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction" ref="atomikosUserTransaction"></property>
<property name="transactionManager" ref="atomikosTransactionManager"></property>
</bean>
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
destroy-method="close" init-method="init" >
<property name="uniqueResourceName" value="atomikos-standalone" />
<property name="maxPoolSize" value="10" />
<property name="minPoolSize" value="5" />
<property name="testQuery" value="SELECT 1" />
<property name="xaDataSource" ref="xaReferent" />
</bean>
<bean id="xaReferent" class="org.h2.jdbcx.JdbcDataSource">
<property name="URL" value="jdbc:h2:~/test-db;MODE=PostgreSQL;MVCC=TRUE;DB_CLOSE_DELAY=-1" />
<property name="user" value="sa" />
<property name="password" value="" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.atomikos.icatch.jta.hibernate4"/>
<property name="jtaTransactionManager" ref="transactionManager" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.transaction.jta.platform">com.atomikos.icatch.jta.hibernate4.AtomikosPlatform</prop>
<prop key="show_sql" >true</prop>
</props>
</property>
</bean>
</beans>
Update
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.atomikos.icatch.jta.hibernate4"/>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.jta.platform">com.atomikos.icatch.jta.hibernate4.AtomikosPlatform</prop>
<prop key="hbm2ddl.auto">create</prop>
<prop key="connection.release_mode">auto</prop>
<prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>

Related

Manage Hibernate and Activiti with Common TransactionManager

I want to use a common transaction manager (JpaTransactionManager) for hibernate and activiti, but i can not! And i have read all internet resources for that! Hear is a simple scenario (which does not even use hibernate!!):
Save variables in task
Save variable in task#execution
Complete task
Scenario implementation (in a spring bean method with #Transactional annotation):
#Component
public class TaskManager {
#Autowired TaskService taskService;
#Autowired RuntimeService runtimeService;
#Transactional
public void completeTask(CompleteTaskRequest request) {
Task task = taskService.createTaskQuery().taskId(request.getTaskId()).singleResult();
if (task == null) {
throw new ActivitiObjectNotFoundException("No task found");
}
taskService.setVariableLocal(task.getId(), "actionDisplayUrl", request.getActionDisplayUrl());
taskService.setVariableLocal(task.getId(), "actionSummaryUrl", request.getActionSummaryUrl());
runtimeService.setVariableLocal(task.getExecutionId(), "prevTaskId", task.getId());
taskService.complete(task.getId());
}
}
It's obvious: if taskService.complete throws error, the whole transaction should be rollbacked, so all saved variables should be rollbacked, and the below test case should be passed:
#Test
#Deployment(resources = "org.activiti.test/CompleteTaskTest.bpmn20.xml")
public void testCompleteTaskWithError() {
Map<String, Object> processVars = new HashMap<>();
processVars.put("error", true); // Causes throwing error in ScriptTaskListener
runtimeService.startProcessInstanceByKey("CompleteTaskTest", processVars);
Task task = taskService.createTaskQuery().taskName("Task 1").singleResult();
CompleteTaskRequest req = new CompleteTaskRequest();
req.setTaskId(task.getId());
req.setActionDisplayUrl("/actions/1234");
req.setActionSummaryUrl("/actions/1234/summary");
try {
taskManager.completeTask(req);
fail("An error expected!");
} catch(Exception e) {
}
// Check variables rollback
assertNull(taskService.getVariableLocal(task.getId(),"actionSummaryUrl"));
assertNull(taskService.getVariableLocal(task.getId(),"actionDisplayUrl"));
assertNull(runtimeService.getVariableLocal(task.getExecutionId(), "prevTaskId"));
}
But it fails, the variables are committed to DB (not rollbacked).
Spring context (Using org.springframework.orm.jpa.JpaTransactionManager as transaction manager):
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="idGenerator" ref="idGenerator"/>
<property name="databaseSchemaUpdate" value="true" />
<property name="jpaEntityManagerFactory" ref="entityManagerFactory" />
<property name="jpaHandleTransaction" value="true" />
<property name="jpaCloseEntityManager" value="true" />
<property name="beans" ref="processEngineBeans" />
<property name="jobExecutorActivate" value="false" />
<property name="asyncExecutorEnabled" value="true" />
<property name="asyncExecutorActivate" value="true" />
</bean>
<aop:config proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="processEngineBeans" class="java.util.HashMap">
<constructor-arg index="0" type="java.util.Map">
<map>
</map>
</constructor-arg>
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
<bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
<bean id="idGenerator" class="org.activiti.engine.impl.persistence.StrongUuidGenerator" />
<bean id="activitiRule" class="org.activiti.engine.test.ActivitiRule">
<property name="processEngine" ref="processEngine" />
</bean>
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="packagesToScan" value="org.activiti.test" />
<property name="defaultDataSource" ref="dataSource" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect_resolvers">org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" >
<property name="proxyTargetClass" value="true" />
</bean>
Versions:
Activiti version: 5.22.0
DB: h2 (Also tested with Oracle in production)
What is wrong with my configurations?
P.S.
The test project is uploaded here.
I have also asked this question in alfresco forum.
UPDATE::
By using org.springframework.jdbc.datasource.DataSourceTransactionManager instead of org.springframework.orm.jpa.JpaTransactionManager the test case passed. But now i can not persist JPA entities.
The problem is solved by resolving conflict between MyBatis (JDBC) and Hibernate (JPA):
jpaVendorAdapter property should be added to entityManagerFactory bean:
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
So entityManagerFactory bean should be like this:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect_resolvers">org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
For more details see answer of this question.

Configure Spring JMS with JTA and Atomikos

I want to achieve the following:
i) we have a weblogic queue and external applications would be writing into the queue
ii)I have to write a stand-alone application which can read and write into this queue inside a transaction. i.e. the messages from the queue has to be persisted into DB. So in case of any error at any stage, the transaction should rollback and the message should be available in the queue again.
To achieve this I have done some self study and came across the below URL:
http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html?page=3
I have understood that I have to use JTA and XA resources for this. I have tried using Atomikos as the JTA Transaction manager following the below URL:
http://www.atomikos.com/Documentation/SpringIntegration
After trying whole day I have comeup with the following incomplete applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="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">
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.provider.url">t3://somehost.corp.com:8011</prop>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
</props>
</property>
</bean>
<!--
This is an interface not a concreate class. Not sure what needs to go here for weblogic queue connection factory.
<bean id="xaFactory" class="javax.jms.XAConnectionFactory">
<property name="brokerURL" value="t3://somehost.corp.com:8011" />
</bean> -->
<bean id="ConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="jms/AuditCF" />
<property name="xaConnectionFactory" ref="xaFactory" />
</bean>
<bean id="JtaTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="myDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jms/AuditQ</value>
</property>
</bean>
<bean id="service" class="com.samples.AccountService">
<property name="jmsTemplate">
<ref bean="jmsTemplate" />
</property>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="ConnectionFactory" />
</property>
<property name="defaultDestination">
<ref bean="myDestination" />
</property>
<property name="destinationResolver" ref="jndiResolver" />
</bean>
<!-- a class that implements javax.jms.MessageListener -->
<bean id="MessageListener" class="com.samples.Messages" />
<bean id="MessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="transactionManager" ref="JtaTransactionManager" />
<property name="connectionFactory" ref="ConnectionFactory" />
<property name="messageListener" ref="MessageListener" />
<property name="destinationName" value="jms/AuditQ" />
<property name="concurrentConsumers" value="1" />
<property name="receiveTimeout" value="3000" />
<property name="sessionTransacted" value="true" />
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>weblogic.jms.XAConnectionFactory</value>
</property>
</bean>
<bean id="jndiResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="cache">
<value>true</value>
</property>
</bean>
<!-- <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="receiveTimeout">
<value>0</value>
</property>
<property name="destinationResolver" ref="jndiResolver" />
</bean> -->
<bean id="datasource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
<!-- set an arbitrary but unique name for the datasource -->
<property name="uniqueResourceName">
<value>XADBMS</value>
</property>
<!-- set the underlying driver class to use, in this example case we use
Oracle -->
<property name="xaDataSourceClassName">
<value>oracle.jdbc.xa.client.OracleXADataSource</value>
</property>
<property name="xaProperties">
<props>
<prop key="user"><user></prop>
<prop key="password"><pwd></prop>
<prop key="URL">jdbc:oracle:thin:#host:3028/DB
</prop>
</props>
</property>
<!-- how many connections in the pool? -->
<property name="poolSize" value="3" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan" value="com.samples">
</property>
<property name="dataSource">
<ref bean="datasource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.connection.isolation">3</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</prop>
<prop key="hibernate.transaction.manager_lookup_class">
com.atomikos.icatch.jta.hibernate4.TransactionManagerLookup
</prop>
</props>
</property>
</bean>
</beans>
As shown in the Spring-Atomikos integration example, the XAConnectionFactory has been mentioned as :
<bean id="xaFactory"
class="org.apache.activemq.ActiveMQXAConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
I am unable to find the related configuration I need to do for weblogic queue. I have tried using "weblogic.jms.XAConnectionFactory" as the class, but I get classnotfoundexception for that.
I dont have any experience working with JTA or XA. Kindly guide me.

Caused by: org.hibernate.HibernateException: No Session found for current thread

I have one Hibernate project as CoreServices with all Hibernate configuration. I have imported the Project jar in my another project But I am getting
error Caused by: org.hibernate.HibernateException: No Session found
for current thread
<context:property-placeholder location="classpath:application.properties" />
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>****.******.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

Spring / Hibernate 4(non JPA) / Infinispan / Atomikos no transaction manager found

I'm using Tomcat7 and need JTA for Infinispan Cache. I am using Spring 3.x with Hibernate 4 (non JPA) and Atomikos for JTA. I can't find a transaction manager look up class in the Atomikos library or docs for Hibernate 4. All examples are for Hibernate version 3 or with use of JPA. Infinispan cannot find a transaction manager.
Here is my config:
<bean id="myDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="rsname" />
<property name="xaDataSourceClassName"
value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
<property name="xaProperties">
<props>
<prop key="URL">${db.url}</prop>
<prop key="user">${db.user}</prop>
<prop key="password">${db.pass}</prop>
</props>
</property>
<property name="maxPoolSize" value="50" />
<property name="minPoolSize" value="20" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingLocations" value="classpath*:hibernate/**/*.hbm.xml" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.cache.region.factory_class=org.hibernate.cache.infinispan.InfinispanRegionFactory
hibernate.cache.use_query_cache=true
hibernate.cache.use_second_level_cache=true
</value>
</property>
</bean>
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.J2eeUserTransaction">
<property name="transactionTimeout" value="300" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="atomikosTransactionManager,atomikosUserTransaction">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
<property name="allowCustomIsolationLevels" value="true" />
</bean>
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="*" rollback-for="Throwable" />
</tx:attributes>
</tx:advice>
Looking at the spring docs setting the jtaTransactionManager property on the LocalSessionFactoryBean should take care of things.
<property name="jtaTransactionManager" ref="transactionManager" />
Basically adding that to the definition of your bean should be enough.
Another note about your configuration, you are using <tx:annotation-driven /> so basically your <tx:advice .. /> does nothing only takes up space.

spring how to write config to support 2 database

i try to config a data source ----> mysql
the other data source ----> h2 in memory (embedded )
with the following config:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost/item"
p:username="" p:password="" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">/ehcache.xml</prop>
</props>
</property>
<property name="packagesToScan" value="*************" />
</bean>
<!-- Spring transaction management -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="org.h2.tools.Server" class="org.h2.tools.Server" scope="singleton" factory-method="createTcpServer"
init-method="start" depends-on="org.h2.tools.Server-WebServer">
<constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,9092"/>
</bean>
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server" scope="singleton" factory-method="createWebServer" init-method="start">
<constructor-arg value="-web,-webAllowOthers,true,-webPort,8082"/>
</bean>
<!-- notice that loading the Driver as a bean is unnecessary is most cases! u could safely remove this and the depends-on in the next bean -->
<bean id="H2DatabaseJDBCDriver" class="org.h2.Driver" scope="singleton" init-method="load" depends-on="org.h2.tools.Server"/>
<bean id="H2InMemoryDB"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
depends-on="org.h2.tools.Server">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:appdb1;DB_CLOSE_DELAY=-1" />
<!-- ;TRACE_LEVEL_FILE=3;TRACE_LEVEL_SYSTEM_OUT=3 -->
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="H2InMemoryDBPool" class="org.apache.commons.pool.impl.GenericObjectPool">
<!-- Two connections: InMemoryEntityManagerFactory and transactionManager -->
<property name="minIdle" value="1"/>
<property name="maxWait" value="10"/>
<property name="maxActive" value="10"/>
<property name="maxIdle" value="10"/>
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
</bean>
<bean id="H2InMemoryDBDSConnFactory" class="org.apache.commons.dbcp.DataSourceConnectionFactory">
<constructor-arg><ref bean="H2InMemoryDB"/></constructor-arg>
</bean>
<bean id="H2InMemoryDBPoolableConnFactory" class="org.apache.commons.dbcp.PoolableConnectionFactory">
<constructor-arg index="0"><ref bean="H2InMemoryDBDSConnFactory"/></constructor-arg>
<constructor-arg index="1"><ref bean="H2InMemoryDBPool"/></constructor-arg>
<constructor-arg index="2"><null/></constructor-arg>
<constructor-arg index="3"><null/></constructor-arg>
<constructor-arg index="4"><value>false</value></constructor-arg>
<constructor-arg index="5"><value>true</value></constructor-arg>
</bean>
<bean id="pooledInMemoryDB" class="org.apache.commons.dbcp.PoolingDataSource" depends-on="H2InMemoryDBPoolableConnFactory">
<constructor-arg><ref bean="H2InMemoryDBPool"/></constructor-arg>
</bean>
<bean id="sessionFactory2"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="pooledInMemoryDB">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
<property name="packagesToScan" value="********" />
</bean>
<bean id="transactionManager2"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
but its not work .
so my question is :
do i need to use 2 session factory or using dynamic data source switch ?
Thanks
I did find a typo that may cause you code to break.
Your second transactionmanager refers to the first sessionFactory. I think you want it to refer to the second transactionmanager. Try:
<bean id="transactionManager2"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory2" />
Regarding your question whether one has to use some sort of "dynamic data source switch" as described here, multiple data sources should just be fine.
i use
<jdbc:embedded-database id="embeddedDatasource" type="DERBY">
<jdbc:script location="classpath:test.sql"/>
</jdbc:embedded-database>
instead
it works

Resources