2010-09-27

Example: how to start EclipseLink (or other JPA) transaction declaratively in Spring

Here is example of declarative transaction management with EclipseLink JPA provider in Spring-based application. Similar approach should work with other JPA providers as well.
I use Maven for building so these were the required dependencies:
  1. <dependency>  
  2.  <groupid>org.eclipse.persistence</groupid>  
  3.  <artifactid>javax.persistence</artifactid>  
  4.  <version>2.0.0</version>  
  5. </dependency>  
  6. <dependency>  
  7.  <groupid>org.aspectj</groupid>  
  8.  <artifactid>aspectjrt</artifactid>  
  9.  <version>1.6.9</version>  
  10. </dependency>  
  11. <dependency>  
  12.  <groupid>org.springframework</groupid>  
  13.  <artifactid>spring-aspects</artifactid>  
  14.  <version>3.0.4.RELEASE</version>  
  15. </dependency>  


Here is Spring's application context file:

  1. <!--xml version="1.0" encoding="UTF-8"?-->  
  2. <beans xmlns="http://www.springframework.org/schema/beans" <brbr="">  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  3.   xmlns:context="http://www.springframework.org/schema/context"   
  4.   xmlns:aop="http://www.springframework.org/schema/aop"   
  5.   xmlns:tx="http://www.springframework.org/schema/tx"   
  6.   xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.   http://www.springframework.org/schema/context  
  9.   http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  10.   http://www.springframework.org/schema/aop  
  11.   http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
  12.   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">  
  13.   
  14.   <context:annotation-config>  
  15.   <context:component-scan base-package="your.services.package">  
  16.   <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor">  
  17.   <tx:annotation-driven transaction-manager="txManager">  
  18.   <aop:spring-configured>  
  19.   
  20.   <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">  
  21.    <property name="entityManagerFactory" ref="emf">  
  22.   </property></bean>  
  23.   <bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">  
  24.     <property name="databasePlatform" value="org.eclipse.persistence.platform.database.OraclePlatform">  
  25.     <property name="showSql" value="true">  
  26.   </property></property></bean>  
  27.   <bean id="emf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">  
  28.    <property name="persistenceUnitName" value="your_persistence_unit_name">  
  29.    <property name="jpaVendorAdapter" ref="jpaAdapter">  
  30.   </property></property></bean>  
  31. </aop:spring-configured></tx:annotation-driven></bean></context:component-scan></context:annotation-config></beans>  


Now inside of your.services.package you can have such class:

  1. @Component //instantiate as Spring's bean  
  2. public class ProductServiceImpl implements ProductService {  
  3.  //Trick part #1 - Spring substitutes here entity manager   
  4.  //and handles it in a way that each thread thinks he's the only one working with this manager.  
  5.  //For E.M. marked by this annotation declarative transaction management is possible  
  6.  @PersistenceContext(type = PersistenceContextType.TRANSACTION)   
  7.  private EntityManager containerEm;  
  8.   
  9.  //Trick part #2 - Spring wraps this method in transaction which is handled by containerEm  
  10.  @Transactional(readOnly=false, propagation=Propagation.REQUIRED)  
  11.  public void yourMethod() {  
  12.    ...  
  13.    //Here you can do whatever you want with E.M.:  
  14.    containerEm.createNativeQuery(...);  
  15.    //or  
  16.    em.persist(...);  
  17.    //etc.  
  18.    ...  
  19.  }//end of transactional method  
  20.   
  21. }  

1 comment:

Prasath Premkumar said...

Are you sure that this configuration will work? i got the following error:
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.1: Element 'tx:annotation-driven' must have no character or element information item [children], because the type's content type is empty.