title: Spring JPA Transaction Manager does not rollback
body: <p>I recently moved from Hibernate to JPA. Now I notice two things in my code.</p>
  
  <ol>
  <li><p>Methods in my services do not need <code>@Transactional</code> anymore to perform insertion to the database.</p></li>
  <li><p>Transaction never get rolled back even if there's any exception.</p></li>
  </ol>
  
  <p><strong>applicationContext.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
      xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
      xmlns:task="http://www.springframework.org/schema/task"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/data/jpa 
      http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
      http://www.springframework.org/schema/tx 
      http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.1.xsd
      http://www.springframework.org/schema/data/jpa
      http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
      http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"&gt;
  
      &lt;context:annotation-config /&gt;
      &lt;context:component-scan base-package="com.myapp.service, com.myapp.batch,com.myapp.auth" /&gt;
      &lt;!-- Configure the data source bean --&gt;
      &lt;bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig"&gt;  
        &lt;property name="dataSourceProperties" &gt;
          &lt;props&gt;
              &lt;prop key="url"&gt;jdbc:mysql://localhost:3306/app?zeroDateTimeBehavior=convertToNull&lt;/prop&gt;
              &lt;prop key="user"&gt;user&lt;/prop&gt;
              &lt;prop key="password"&gt;pass&lt;/prop&gt;
          &lt;/props&gt;
        &lt;/property&gt; 
        &lt;property name="dataSourceClassName"   
                  value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" /&gt;  
      &lt;/bean&gt;  
  
      &lt;bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"&gt;  
            &lt;constructor-arg ref="hikariConfig" /&gt;  
      &lt;/bean&gt;
      &lt;!-- Create default configuration for Hibernate --&gt;
      &lt;bean id="hibernateJpaVendorAdapter"
          class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /&gt;
      &lt;!-- Configure the entity manager factory bean --&gt;
      &lt;bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
          &lt;property name="packagesToScan" value="com.myapp.persist" /&gt;
          &lt;property name="jpaVendorAdapter"&gt;
              &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /&gt;
          &lt;/property&gt;
          &lt;property name="jpaProperties"&gt;
              &lt;props&gt;
                  &lt;prop key="hibernate.hbm2ddl.auto"&gt;update&lt;/prop&gt;
                  &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQL5Dialect&lt;/prop&gt;
                  &lt;prop key="hibernate.show_sql"&gt;false&lt;/prop&gt;
                  &lt;prop key="hibernate.c3p0.timeout"&gt;100&lt;/prop&gt;
              &lt;/props&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
      &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
          &lt;property name="entityManagerFactory" ref="entityManagerFactory" /&gt;
      &lt;/bean&gt;
      &lt;bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer"
          depends-on="entityManagerFactory"&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
          &lt;property name="databasePopulator"&gt;
              &lt;bean
                  class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator"&gt;
                  &lt;property name="scripts" value="classpath:initial_data.sql" /&gt;
                  &lt;property name="continueOnError" value="true" /&gt;
              &lt;/bean&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
      &lt;jpa:repositories base-package="com.myapp.repositories"
          entity-manager-factory-ref="entityManagerFactory" /&gt;
      &lt;!-- Enable annotation driven transaction management --&gt;
      &lt;tx:annotation-driven /&gt;
      &lt;task:annotation-driven /&gt;
  &lt;/beans&gt;
  </code></pre>
  
  <p><strong>NetworkService.java</strong></p>
  
  <pre><code>@Service
  public class AdminUserManagementService {
  
      @Autowired
      UserRepository userRepository;
  
      @Autowired
      UserService userService;
  
      @Autowired
      RequestRegisterHistoryRepository requestRegisterHistoryRepository;
  
      @Autowired
  
      @Transactional(rollbackFor=Exception.class)
      public User saveUser(UserBO userBO){
          RequestRegisterHistory requestRegisterHistory = new RequestRegisterHistory();
          User user = new User();
          // ..
          requestRegisterHistoryRepository.save(requestRegisterHistory);
          userRepository.save(user);
          return user;
      }       
  }
  </code></pre>
  
  <p><strong>mvc-dispatcher-servlet.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans:beans xmlns="sec://www.springframework.org/schema/mvc"
      xmlns:beans="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
          http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"&gt;
  
      &lt;context:component-scan base-package="com.myapp.controller" /&gt;
  
      &lt;!-- Enables the Spring MVC @Controller programming model --&gt;
      &lt;mvc:annotation-driven /&gt;
  
      &lt;!-- Handles HTTP GET requests for /resources/** by efficiently serving 
          up static resources in the ${webappRoot}/resources directory --&gt;
      &lt;mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/" /&gt;
  
      &lt;mvc:resources mapping="/resources/**" location="resources/" /&gt;
  
      &lt;!-- Resolves views selected for rendering by @Controllers to .jsp resources 
          in the /WEB-INF/views directory --&gt;
  
  
      &lt;beans:bean
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;
          &lt;beans:property name="prefix" value="/WEB-INF/views/" /&gt;
          &lt;beans:property name="suffix" value=".jsp" /&gt;
          &lt;beans:property name="order" value="1" /&gt;
      &lt;/beans:bean&gt;
  
  &lt;beans:bean id="contentNegotiationManager"
               class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"&gt;
      &lt;beans:property name="favorPathExtension" value="false" /&gt;
      &lt;beans:property name="favorParameter" value="true" /&gt;
      &lt;beans:property name="parameterName" value="mediaType" /&gt;
      &lt;beans:property name="ignoreAcceptHeader" value="true"/&gt;
      &lt;beans:property name="useJaf" value="false"/&gt;
      &lt;beans:property name="defaultContentType" value="application/json" /&gt;
  
      &lt;beans:property name="mediaTypes"&gt;
          &lt;beans:map&gt;
              &lt;beans:entry key="json" value="application/json" /&gt;
              &lt;beans:entry key="xml" value="application/xml" /&gt;
         &lt;/beans:map&gt;
      &lt;/beans:property&gt;
  &lt;/beans:bean&gt;
  
      &lt;mvc:interceptors&gt;
          &lt;beans:bean
              class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"&gt;
              &lt;beans:property name="paramName" value="lang" /&gt;
          &lt;/beans:bean&gt;
          &lt;beans:bean class="com.myapp.component.AppInterceptor" /&gt;
      &lt;/mvc:interceptors&gt;
  
      &lt;beans:bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"&gt;
              &lt;beans:property name="supportedMediaTypes" value="image/jpeg" /&gt;
      &lt;/beans:bean&gt;
  
      &lt;beans:bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver"&gt;
  
           &lt;!-- setting maximum upload size --&gt;
          &lt;beans:property name="maxUploadSize" value="99999999999" /&gt;
      &lt;/beans:bean&gt;
  &lt;/beans:beans&gt;
  </code></pre>
  
  <p>I am using <code>Spring Version : 4.1.4</code> and <code>MySQL Table : MyISAM</code></p>
  
  <p><strong>Stacktrace</strong></p>
  
  <pre><code>org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
      at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:248)
      at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:214)
      at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
      at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
      at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
      at com.sun.proxy.$Proxy37.save(Unknown Source)
      at com.myapp.service.AdminUserManagementService.saveUser(AdminUserManagementService.java:460)
      at com.myapp.service.AdminUserManagementService$$FastClassBySpringCGLIB$$f21244b7.invoke(&lt;generated&gt;)
      at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
      at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
      at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
  </code></pre>
  
  <p>How do I configure so I would require <code>@Transactional</code> annotation and any transaction get rolled back during exceptions ?</p>