Hi i am try to develop spring and hibernate app with transactions , i am using spring 4.x and hibernate 4.x , here is my code snippet
applicationContext.xml
<tx:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.xyx.service" />
<context:component-scan base-package="com.xyz.dao" />
<import resource="conf/spring/persistence.xml" />
servlet-context.xml
<context:component-scan base-package="com.xyx.webservice.components" />
<mvc:annotation-driven />
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</bean>
<!-- Configure to plugin JSON as request and response in method handler -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonMessageConverter"/>
</list>
</property>
</bean>
persistance.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/xyx" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="packagesToScan" value="com.xyz.model" />
<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">false</prop>
</props>
</property>
</bean>
<bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager" p:sessionFactory-ref= "sessionFactory" >
</bean>
</beans>
and finnaly meservice look like this
#Transactional(propagation=Propagation.REQUIRED,rollbackFor=RuntimeException.class)
public Object loadCategories(UserContactsInputVO inputVo) {
User user= getUserObject(inputVo);
userDAO.saveOrUpdateForTrancasction(user);
System.out.println(user.getUserId());
//getAudioFilesBasedOnCategories();
try{
return getAudioFilesBasedOnCategories();
}catch (RuntimeException e) {
e.printStackTrace();
}
return new CategoryResponseVo();
}
and
#Transactional(propagation=Propagation.REQUIRED)
public CategoryResponseVo getAudioFilesBasedOnCategories()
{
try{
if(true)
throw new RuntimeException();
}finally{
}
return vo;
}
here runtime exception occurs but db records are not rolled backed.
The reason the transaction is not getting rolled back is beacause the RuntimeException is not getting propagated to the actual Spring proxy which manages the transaction rollback code. And the reason it is not being propagated is that you have caught it and have not rethrown.
try{
return getAudioFilesBasedOnCategories();
}catch (RuntimeException e) {
e.printStackTrace(); //**THIS IS WRONG**
}
Instead do this
try{
return getAudioFilesBasedOnCategories();
}catch (RuntimeException e) {
//log the error
throw e; // throw back
}
Also you probably do not need to give rollbackFor attribute as by default on RuntimeException, the transaction is rolled back.
Related
I 've come across a scenario where I have to keep track of various exceptions on various conditions in my batch written using spring batch.
For eg: If while reading database is not available throw certain type of exception and send a mail stating database is not available and terminate batch.
if table is not available then throw some other exception and send a mail stating table is not available and terminate batch.
and if data is not meeting the conditions specified in sql statement don't do anything as this is a normal termination of job.
All I am able to achieve till now is using StepExecutionListener where I can see if batch read any records or what is the failureException but not in a way I want.
Any help/suggestions would do.
My context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<import resource="classpath:context-datasource.xml" />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>springbatch.properties</value>
</property>
</bean>
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<!-- ItemReader which reads from database and returns the row mapped by
rowMapper -->
<bean id="databaseItemReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="SELECT * FROM employee1" />
<property name="rowMapper">
<bean class="com.abc.springbatch.jdbc.EmployeeRowMapper" />
</property>
</bean>
<!-- ItemWriter writes a line into output flat file -->
<bean id="databaseItemWriter"
class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
insert into actemployee(empId, firstName, lastName,additionalInfo)
values (?, ?, ?, ?)
]]>
</value>
</property>
<property name="itemPreparedStatementSetter">
<bean class="com.abc.springbatch.jdbc.EmployeePreparedStatementSetter" />
</property>
</bean>
<!-- Optional ItemProcessor to perform business logic/filtering on the input
records -->
<bean id="itemProcessor" class="com.abc.springbatch.EmployeeItemProcessor">
<property name="validator" ref="validator" />
</bean>
<!-- Step will need a transaction manager -->
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="recordSkipListener" class="com.abc.springbatch.RecordSkipListener" />
<bean id="customItemReadListener" class="com.abc.springbatch.CustomItemReadListener" />
<bean id="stepExecutionListener" class="com.abc.springbatch.BatchStepExecutionListner">
<constructor-arg ref="mailSender" />
<constructor-arg ref="preConfiguredMessage" />
</bean>
<!-- Actual Job -->
<batch:job id="employeeToActiveEmployee">
<batch:step id="step1">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="databaseItemReader" writer="databaseItemWriter"
processor="itemProcessor" commit-interval="10" skip-limit="500" retry-limit="5">
<batch:listeners>
<batch:listener ref="customItemReadListener"/>
</batch:listeners>
<!-- Retry included here to retry for specified times in case the following exception occurs -->
<batch:retryable-exception-classes>
<batch:include
class="org.springframework.dao.DeadlockLoserDataAccessException" />
</batch:retryable-exception-classes>
<batch:skippable-exception-classes>
<batch:include class="javax.validation.ValidationException" />
</batch:skippable-exception-classes>
</batch:chunk>
</batch:tasklet>
<batch:listeners>
<batch:listener ref="recordSkipListener" />
<batch:listener ref="stepExecutionListener" />
</batch:listeners>
</batch:step>
</batch:job>
<!-- Email API bean configuarion -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${constant.order.mailHost.response}" />
<property name="port" value="${constant.order.mailPort.response}" />
<property name="username" value="${constant.order.mailUsername.response}" />
<property name="password" value="XXXXXX" />
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">false</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
<bean id="preConfiguredMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="abc#xyz.com" />
<property name="to" value="abc#xyz.com" />
<property name="subject" value="Skipped Records" />
</bean>
</beans>
<!-- Email API bean configuarion -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${constant.order.mailHost.response}" />
<property name="port" value="${constant.order.mailPort.response}" />
<property name="username" value="${constant.order.mailUsername.response}" />
<property name="password" value="XXXXXX" />
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">false</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
<bean id="preConfiguredMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="abc#xyz.com" />
<property name="to" value="abc#xyz.com" />
<property name="subject" value="Skipped Records" />
</bean>
StepExecutionListener.java
public class BatchStepExecutionListner implements StepExecutionListener {
private JavaMailSender mailSender;
private SimpleMailMessage simpleMailMessage;
public BatchStepExecutionListner(JavaMailSender mailSender, SimpleMailMessage preConfiguredMessage) {
// TODO Auto-generated constructor stub
this.mailSender = mailSender;
this.simpleMailMessage = preConfiguredMessage;
}
#Override
public void beforeStep(StepExecution stepExecution) {
// TODO Auto-generated method stub
}
#Override
public ExitStatus afterStep(StepExecution stepExecution) {
// TODO Auto-generated method stub
stepExecution.getReadCount();
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(simpleMailMessage.getFrom());
helper.setTo(simpleMailMessage.getTo());
helper.setSubject(simpleMailMessage.getSubject());
helper.setText("These are the skipped records");
FileSystemResource file = new FileSystemResource("filename.txt");
helper.addAttachment(file.getFilename(), file);
} catch (MessagingException e) {
throw new MailParseException(e);
}
//mailSender.send(message);
return null;
}
}
Thanks
If the database is down, you'll fail to create the data source as you initialize your application context (well before you enter the job execution). Beyond that, you really should think about limiting the scope of what is "reasonable" to catch within the application. Generally (at least in our shop) a DB failure, network issue, or dropped table would be considered a "catastrophic" failure, so we don't bother catching them in application code.
There should be other tools in place to monitor network/system/database health and configuration management tools in place to make sure your databases have the proper DDL in place. Any further checks in your application layer would be redundant.
The ItemWriteListener has onWriteError() and the ItemReadListener has onReadError() method. This can be used to handle different exceptions and take action.
I'm developing a web app application with spring 4, jsf 2 and hibernate 5. To manage transactional operation in hibernate in web context, i use the OpenSessionInViewFilter in web.xml.
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
My spring context configuration about dataSource is:
<bean id="dataSource" class="com.p6spy.engine.spy.P6DataSource">
<constructor-arg>
<bean 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>
</constructor-arg>
</bean>
<!-- Hibernate 5 Annotation SessionFactory Bean definition -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>org.dummy.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.flushMode">COMMIT</prop>
<prop key="org.hibernate.flushMode">COMMIT</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<context:annotation-config />
<context:component-scan base-package="org.dummy.persistence" />
<aop:aspectj-autoproxy />
<tx:annotation-driven mode="aspectj" transaction-manager="txManager" />
UPDATED
My application listener is
#Component
public class SimplePopulator implements ApplicationListener<ContextRefreshedEvent> {
#Autowired
protected UserFacadeService userFacadeService;
#Autowired
protected SessionFactory sessionFactory;
#Override
#Transactional
public void onApplicationEvent(ContextRefreshedEvent event) {
try {
////sessionFactory.set
//Session session = sessionFactory.openSession();
//session.beginTransaction();
#SuppressWarnings("unused")
UserAccount account1 = userFacadeService.createUserAccount("testAA", "testAA", "User Dummy", "dummy#email.org");
//session.save(account1);
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
System.out.println(userFacadeService.existsAccount("test"));
//session.getTransaction().commit();
//session.close();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When i launch the application, on application listener execution i receive the following exception:
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:132)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:692)
at org.abubu.whisper.persistence.impl.AbstractRepository.getCurrentSession(AbstractRepository.java:46)
at org.abubu.whisper.persistence.impl.UserAccountRepositoryImpl.findByUsername(UserAccountRepositoryImpl.java:26)
I need to use transaction in spring context event listener, so i can not use OpenSessionInViewFilter because it works only for web request. I think i can use OpenSessionInterceptor with AOP, but i did not find any example about use it.
How can i use OpenSessionInterceptor with AOP?
Hi i'm trying to save into two database simultaneously but I always get an error.
Exception in thread "main" org.hibernate.HibernateException: No Session found for current thread
here's my code :
#Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW, readOnly=false)
public void save(ArsenalPlayer domain1, ArsenalPlayer2 domain2)
throws Exception {
dao1.save(domain1);
dao2.save(domain2);
}
dao1 uses a sessionFactory attached to datasource1
dao2 uses a sessionFactory attached to datasource2
and here's my configuration
DataSource
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/arsenal" />
<property name="user" value="root" />
<property name="password" value="ahmids" />
</bean>
SessionFactory
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="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.format_sql">update</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.gongfu4.bean.ArsenalPlayer</value>
</list>
</property>
</bean>
DataSource2
<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/arsenal2" />
<property name="user" value="root" />
<property name="password" value="ahmids" />
</bean>
SessionFactory2
<bean id="sessionFactory2"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">update</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.gongfu4.bean.ArsenalPlayer2</value>
</list>
</property>
</bean>
applicationContext
<context:component-scan base-package="com.gongfu4" />
<context:annotation-config />
<import resource="dataSource.xml" />
<import resource="dataSource2.xml" />
<import resource="hibernate.xml" />
<import resource="hibernate2.xml" />
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="myTx"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory2" />
</bean>
and here are my dao classes :
DAO1
#Autowired
SessionFactory sessionFactory;
public void save(ArsenalPlayer domain) {
sessionFactory.getCurrentSession().save(domain);
}
DAO2
#Autowired
SessionFactory sessionFactory2;
public void save(ArsenalPlayer2 domain) {
sessionFactory2.getCurrentSession().merge(domain);
}
Is there something wrong with my configuration?
You cannot use those two transaction managers like that. You have two data sources, two transaction managers and, from your code, I understand that you want the two save operations to be performed in the same transaction. The question is "a transaction from which transaction manager?".
The way you have the code and the configuration, Spring will use the "default" transaction manager because <tx:annotation-driven/> by default will search for a transaction manager bean with the id "transactionManager" and the bean with this id is the one for data source dataSource. But your code is not working and this is the expected behavior. Spring will open a Hibernate session using sessionFactory and the dao1.save(domain1); call will succeed because this is the correct Hibernate session for the correct dataSource. But when the dao2.save(domain2); method is called you will have the same session from dao1 call but be used for a db operation for the second database.
As I see it you have two options:
Use a JTA transaction manager to coordinate the two datasources. With a JTA the two save operations will be atomic. If one fails, then both are rolled back.
Perform the two save(domain) operations in two different transactions properly configuring the #Transactional annotation to use the correct transaction manager. In this case, the two save operations will not be atomic. If one save fails then only that one will be rolled-back. See below an exempt taken from the Spring reference documentation here:
public class TransactionalService {
#Transactional("order")
public void setSomething(String name) { ... }
#Transactional("account")
public void doSomething() { ... }
}
<tx:annotation-driven/>
<bean id="transactionManager1" class="org.springframework.jdbc.DataSourceTransactionManager">
...
<qualifier value="order"/>
</bean>
<bean id="transactionManager2" class="org.springframework.jdbc.DataSourceTransactionManager">
...
<qualifier value="account"/>
</bean>
Your current configuration doesn't support global transactions (XA) and therefore you can't span one Transaction on two different databases.
For this reason you need two Hiberante transaction managers, one for each session factory. Then you need to instruct the transactional service which transaction manager should be used.
So instead of:
#Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW, readOnly=false)
public void save(ArsenalPlayer domain1, ArsenalPlayer2 domain2)
throws Exception {
dao1.save(domain1);
dao2.save(domain2);
}
you should have:
<bean id="txManager1" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory1" />
</bean>
<bean id="txManager2" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory2" />
</bean>
#Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW, readOnly=false, value="txManager1")
public void save(ArsenalPlayer domain1)
throws Exception {
dao1.save(domain1);
}
#Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW, readOnly=false, value="txManager2")
public void save(ArsenalPlayer domain2)
throws Exception {
dao2.save(domain2);
}
This is odd but I may be missing something here
I am using quartz to initialize the spring config xml. When I trigger the quartz job first time, the transaction gets rolled back when a Exception occurs. But when the same job is triggered again, the transaction is not rolled back for the same Exception.
I can see from the log that when the job is triggered first time, the datasource (jndi lookup of Sybase Jconnect 7 from Websphere datasources) is initialized (not second time).
Service Layer
#Transactional(value="transactionManager", propagation=Propagation.REQUIRES_NEW, rollbackFor=Exception.class)
public void saveInfo(
List<Foo> saveData) throws Exception {
try{
myDAO.saveInfo(saveData); //data to rollback on exception. Works First time only :(
}
catch(Exception ex){
logBO.createActivityLog("Error Saving Data");
throw ex;
}
}
Spring-config.xml
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
I have played around with all propagation settings REQUIRED/REQUIRES_NEW/without propagation.
DAO method does a bulk update (jdbcTemplate)
EDIT
During the first time, this line is logged
J2CA0086W: Shareable connection MCWrapper id 4c384c38 Managed
connection WSRdbManagedConnectionImpl#6f5a6f5a
State:STATE_TRAN_WRAPPER_INUSE from resource mydatasource was used
within a local transaction containment boundary.
try this :
#TransactionConfiguration(transactionManager = "txManager",defaultRollback = true)
#Transactional
hibernate and datasource code :
<!-- Hibernate Related Configuration. -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://192.168.1.9:5432/dbname"/>
<property name="username" value="postgres"/>
<property name="password" value="pwd"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.domain"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
and txManager :
<!-- Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
don't forget to add line :
<property name="packagesToScan" value="com.domain"/>
in sessionfactory, due to this so many times problem occur.
My project initially develop using with out persistence unit and project is spring,Struts2 hibernate intergration one. Now I need to use jboss connection pool and persistence unit.
Can any one guild me to shortest way to convert project in that requirement.
current spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>properties/database.properties</value>
</property>
</bean>
<bean id="springdatasource"
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.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="springdatasource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>model.AtOrganisation</value>
<value>model.AtDivision</value>
</list>
</property>
</bean>
<bean id="orgdao" class="dao.OrganisationDaoImp">
<property name="sessionfactory" ref="sessionFactory" />
</bean>
<bean id="divdao" class="dao.DevisionDaoImpl">
<property name="sessionfactory" ref="sessionFactory" />
</bean>
<bean id="empAction" class="action.OraganisationAction">
<property name="orgdao" ref="orgdao" />
</bean>
<bean id="empAction2" class="action.DevisionAction">
<property name="orgdao" ref="orgdao" />
</bean>
<bean id="divAction" class="action.DevisionAction">
<property name="divdao" ref="divdao" />
</bean>
sample DAO class
public class DevisionDaoImpl implements DevisionDao {
private SessionFactory sessionfactory;
public void setSessionfactory(SessionFactory sessionfactory) {
this.sessionfactory = sessionfactory;
}
#Override
public List showDiv() {
// TODO Auto-generated method stub
return null;
}
#Override
public void addDiv(AtDivision div) {
Session session = sessionfactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.saveOrUpdate(div);
tx.commit();
//System.out.println("after save : " + org.getAoId());
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
}
}
1: change your datasource config to use the jboss datasource. This can be done like this :
<jee:jndi-lookup id="springdatasource" jndi-name="your-de-jndi-name" />
2: Add a transaction manager to control the transactions using spring transaction manager:
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
3: Add annotation support for spring transactions. Add this to your config:
<tx:annotation-driven transaction-manager="transactionManager" />
4: Finally decorate your Dao classes with #Transactional