Labels

.NET Job Questions About Java Absract class Abstract class Abstract Class and Interface Aggregation ajax aop apache ofbiz Apache ofbiz tutrial Association authentication autocad basics batch Binary Tree bootstrap loader in java build Builder design pattern C++ Job Questions caching CallableStatement in java certifications Chain of responsibility Design pattern charts check parentheses in a string Classes classloader in java classloading concept code quality collage level java program Composition concurrency Concurrency Tutorial Converting InputStream to String Core Java core java concept core java interview questions Core Java Interview Questions Core Java Questions core java tutorial CyclicBarrier in Java data structures database Database Job Questions datetime in c# DB Db2 SQL Replication deserialization in java Design Patterns designpatterns Downloads dtd Eclipse ejb example/sample code exception handling in core java file handling injava File I/O vs Memory-Mapped Filter first program in spring flex Garbage Collection Generics concept in java grails groovy and grails Guice Heap hibernate Hibernate Interview Questions how-to IBM DB2 IBM DB2 Tutorial ide immutable Interceptor Interface interview Interview Questions for Advanced JAVA investment bank j2ee java JAVA Code Examples Java 7 java changes java class loading JAVA Classes and Objects Java Classloader concept Java classloading concept java cloning concept java collection Java collection interview questions Java Collections java concurrency Java CountDownLatch java definiton Java design pattern Java EE 5 Java EE 6 Java Exceptions Java file Java Garbage Collection Java generics Java Glossary java hot concept java immutable concept Java Interface Java interview Question java interview question 2012 java interview question answer Java Interview Questions Java Interview Questions and Answers java interview topic java investment bank Java Job Questions java multithreading java multithreading concept java new features Java Packages java proxy object java questions Java Serialization Java serialization concept java serialization interview question java session concept java string Java Swings Questions java synchronization java threading Java Threads Questions java tutorial java util; java collections; java questions java volatile java volatile interview question Java Wrapper Classes java.java1.5 java.lang.ClassCastException JavaNotes javascript JAX-WS jdbc JDBC JDBC Database connection jdk 1.5 features JDK 1.5 new features Concurrent HashMap JMS interview question JMS tutorial job JSESSIONID concept JSESSIONID interview Question JSF jsp JSP Interview Question JSP taglib JSTL with JSP Junit Junit Concept Junit interview question.Best Practices to write JUnit test cases in Java JVM Linux - Unix tutorial Marker Interfaces MD5 encryption and decryption messaging MNC software java interview question musix NCR java interview question Networking Job Questions news Object Serialization Objects ojdbc14.jar OOP Oracle Oracle SQL Query for two timestamp difference orm own JavaScript function call in Apache ofbiz Packages Palm Apps patterns pdf persistence Portal Portlet Spring Integration Prime number test in java programs Rails Reboot remote computers REST Ruby Sample application schema SCJP security Senior java developer interviews servlet3 servlets session tracking singleton design pattern Spring Spring 2.5 Framework spring ebook Spring framework concept spring MVC spring pdf Spring Security Spring Security interview questions SQL SQL performance SQL Query to create xml file Sql Query tuning ssis and ssrs StAX and XML string concept string immutable string in java strings struts Struts2 Struts2 integration synchronization works in java Technical Interview testing tips Tomcat top Tutorial Volatile in deep Volatile working concept web Web Developer Job Questions web services weblogic Weblogic Application Server websphere what is JSESSIONID xml XML parsing in java XML with Java xslt


Wednesday, 17 July 2013

Integrating Spring and Hibernate: Transactions

In the previous post, I described different ways in which spring and hibernate can
be integrated. In this post I will describe how to use Spring's transaction features
in hibernate. The following methods of transaction management with spring and hibernate are discussed.
  1. Declarative Transaction Mangement with AOP Interceptors
  2. Schema-based Declarative Transaction Management
  3. Schema-based Declarative Transaction Management with Annotations
  4. Programmatic Transaction Management

The easiest way to check if transactions are working for this example is to remove the transaction declarations for the getStockQuote() method. Removing transactions will cause the following exception
org.hibernate.LazyInitializationException: could not initialize proxy - no Session

There's More ...
For this example, start off with the following as described in the "Integrating Spring and Hibernate" post.
  1. The bean StockQuoteBean
  2. The Portfolio classes : PortfolioDAO, PortfolioDAOSupport and PortfolioDAOTemplate
  3. The hibernate mapping file stockquote.hbm.xml

The following main class can be used:
package springhibernate;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class SpringHibernateTest {


public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

IPortfolioService portfolioService = (IPortfolioService) ctx.getBean("portfolioService");
System.out.println("Portfolio Service type : " + portfolioService.getClass());
portfolioService.getStockQuote("123");
}


}
SpringHibernateTest.java

Note that here we use an Interface IPortfolioService, and also note the change to ApplicationContext instead of a BeanFactory.
The reason for using ApplicationContext is enable the use of AOP for declarative transaction management. Also we are not expecting any return to the main class as all the execution is expected to happen in the transaction context.

The Portfolio Service Interface:
package springhibernate;

import beans.StockQuoteBean;

public interface IPortfolioService {

public void getStockQuote(String id);

public void updateStockQuote(StockQuoteBean stockQuoteBean);

}
IPortfolioService.java

Declarative Transaction Management

Declarative transaction management in Spring has the advantage of being less invasive. There is no need for changing application code when using declarative transactions. All you have to do is to modify the application context.

The Service class will be same for all the modes of Declarative transaction management described below.
package springhibernate;

import beans.StockQuoteBean;
import dao.PortfolioDAO;


public class PortfolioService implements IPortfolioService {
private PortfolioDAO portfolioDAO;



public void getStockQuote(String id) {
StockQuoteBean result = portfolioDAO.getStockQuote(id);
System.out.println("Result in Service : " + result.getStockSymbol());

}

public void updateStockQuote(StockQuoteBean stockQuoteBean) {
portfolioDAO.updateStockQuote(stockQuoteBean);
}

public PortfolioDAO getPortfolioDAO() {
return portfolioDAO;
}

public void setPortfolioDAO(PortfolioDAO portfolioDAO) {
this.portfolioDAO = portfolioDAO;
System.out.println("Setting portfolio DAO to : " + portfolioDAO.getClass());
}

}
PortfolioService.java

Declarative Transaction Management with AOP Interceptor

In this method, you have to define a proxy for the bean that will be made transactional.
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<bean id="portfolioDAOTemplate" class="dao.PortfolioDAOTemplate">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>

<bean id="portfolioDAOSupport" class="dao.PortfolioDAOSupport">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>

<bean id="myPortfolioService" class="springhibernate.PortfolioService">
<property name="portfolioDAO" ref="portfolioDAOTemplate"></property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributeSource">
<value>springhibernate.PortfolioService.*=PROPAGATION_REQUIRED</value>
</property>
</bean>

<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="portfolioService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="myPortfolioService"></property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
<value>hibernateInterceptor</value>
</list>
</property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521/xe" />
<property name="username" value="appUser" />
<property name="password" value="password" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>stockquote.hbm.xml</value>
</list>
</property>

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

</beans>
applicationContext.xml

Note that the transactionInterceptor and hibernateTransactionInterceptor are declared. While transactionInterceptor is used to set the transaction properties, the hibernateTransactionInterceptor will manage the hibernate transactions.

Schema-based Declarative Transaction Management

<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<bean id="portfolioDAOTemplate" class="dao.PortfolioDAOTemplate">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>

<bean id="portfolioDAOSupport" class="dao.PortfolioDAOSupport">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>

<bean id="portfolioService" class="springhibernate.PortfolioService">
<property name="portfolioDAO" ref="portfolioDAOTemplate"></property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<aop:config>
<aop:pointcut id="serviceMethods" expression="execution(* springhibernate.IPortfolioService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
</aop:config>

<tx:advice id="txAdvice" transaction-manager="transactionManager" >
<tx:attributes>
<tx:method name="*" propagation="REQUIRES_NEW" />
</tx:attributes>
</tx:advice>


<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521/xe" />
<property name="username" value="appUser" />
<property name="password" value="password" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>stockquote.hbm.xml</value>
</list>
</property>

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

</beans>
applicationContext.xml
Using Schema-based declarative transaction management is a lot simpler and a lot cleaner. However it is adviced that this method not be used in conjunction with explicit auto-proxying using BeanNameAutoProxyCreator, as it might raise issues like advice not being woven etc. Note that the AOP pointcut is defined to be all methods on the IPortfolioService inteface.

Schema-based Declarative Transaction Management with Annotations

<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<bean id="portfolioDAOTemplate" class="dao.PortfolioDAOTemplate">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>

<bean id="portfolioDAOSupport" class="dao.PortfolioDAOSupport">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>

<bean id="portfolioService" class="springhibernate.PortfolioService">
<property name="portfolioDAO" ref="portfolioDAOTemplate"></property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521/xe" />
<property name="username" value="appUser" />
<property name="password" value="password" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>stockquote.hbm.xml</value>
</list>
</property>

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

</beans>
applicationContext.xml
When using annotations, you only have to declare the transaction manager and add <tx:annotation-driven/> to the application context. If the transaction manager is named "transactionManager" then you don't have to declare a transaction-manager attribute for <tx:annotation-driven/> as it happens to be the default value for that attribute.
Also we have to declare the pointcuts in the Service class itself. Note that as annotations are not inherited, declaring the annotations has to be done at the class level.
@Transactional
public class PortfolioService implements IPortfolioService {
private PortfolioDAO portfolioDAO;...

Programmatic Transaction Management

For programmatic transaction management in spring, you will need a PlatformTransctionManger in your bean which will be used to create a TransactionTemplate. The TransactionTemplate is used in the same way the HibernateTemplate was used in previous example. Additionally you will have to create a HibernateTransactionManager as shown in the above example.
package springhibernate;

import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import beans.StockQuoteBean;
import dao.PortfolioDAO;

public class PortfolioServiceTransaction implements IPortfolioService{
private PortfolioDAO portfolioDAO;

private PlatformTransactionManager transactionManager;

public void getStockQuote(final String id) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {

public void doInTransactionWithoutResult(TransactionStatus status) {
StockQuoteBean result = portfolioDAO.getStockQuote(id);
System.out.println("Symbol in transaction " + result.getStockSymbol());
}
});

}

public void updateStockQuote(final StockQuoteBean stockQuoteBean) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {

public void doInTransactionWithoutResult(TransactionStatus status) {
portfolioDAO.updateStockQuote(stockQuoteBean);
}
});

}

public PortfolioDAO getPortfolioDAO() {
return portfolioDAO;
}

public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}

public void setPortfolioDAO(PortfolioDAO portfolioDAO) {
this.portfolioDAO = portfolioDAO;
System.out.println("Setting portfolio DAO to : " + portfolioDAO.getClass());
}

}
PortfolioService.java

No comments:

Post a Comment

LinkWithin

Related Posts Plugin for WordPress, Blogger...