title: Strange behaviour with @Transactional(propagation=Propagation.REQUIRES_NEW)
body: <p><strong>Here is my problem :</strong> </p>
  
  <p>I'm running a batch on a Java EE/Spring/Hibernate application. This batch calls a <code>method1</code>. This method calls a <code>method2</code> which can throw <code>UserException</code> (a class extending <code>RuntimeException</code>). Here is how it looks like : </p>
  
  <pre><code>@Transactional
  public class BatchService implements IBatchService {
   @Transactional(propagation=Propagation.REQUIRES_NEW)
   public User method2(User user) {
     // Processing, which can throw a RuntimeException
   }
  
   public void method1() {
     // ...
     try {
       this.method2(user);
     } catch (UserException e) {
       // ...
     }
     // ...
   }
  }
  </code></pre>
  
  <p>The exception is catched as the execution continues, but at the end of <code>method1</code> when the transaction is closed a RollbackException is thrown.</p>
  
  <p><strong>Here is the stack trace :</strong></p>
  
  <pre><code>org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
      at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
  at $Proxy128.method1(Unknown Source)
  at batch.BatchController.method1(BatchController.java:202)
  </code></pre>
  
  <p>When <code>method2</code> is not throwing this exception, it works well.</p>
  
  <p><strong>What I have tried:</strong></p>
  
  <ul>
  <li>Setting <code>@Transactional(noRollbackFor={UserException.class}))</code> on <code>method1</code></li>
  <li>Try and catch in <code>method2</code></li>
  </ul>
  
  <p>But it didn't change anything.</p>
  
  <p>As the exception is thrown in a different transaction where a rollback happened I don't understand why it doesn't work. I had a look at this : <a href="https://stackoverflow.com/questions/11418290/jpa-transaction-javax-persistence-rollbackexception-transaction-marked-as-rollb">Jpa transaction javax.persistence.RollbackException: Transaction marked as rollbackOnly</a> but it didn't really help me.</p>
  
  <p>I will be very greatful if someone could give me a clue.</p>
  
  <p><strong>Update</strong></p>
  
  <p>I've made it work by setting <code>propagation=Propagation.REQUIRES_NEW</code> on the method called by <code>method2</code> (which is actually the one which is sending the exception). This method is defined in a class very similar to my <code>BatchService</code>. So I don't see why it works on this level and not on <code>method2</code>.</p>
  
  <ul>
  <li>I've set <code>method2</code> as public as the annotation <code>@Transactional</code> is not taken into account if the method is private as said in the documentation :</li>
  </ul>
  
  <blockquote>
    <p>The @Transactional annotation may be placed before an interface
    definition, a method on an interface, a class definition, or a public
    method on a class.</p>
  </blockquote>
  
  <ul>
  <li>I also tried to use <code>Exception</code> instead of <code>RuntimeException</code> (as it is more appropriate) but it also didn't change anything.</li>
  </ul>
  
  <p>Even if it is working the question remains open as it has a strange behaviour and I would like to understand why it's not acting like it should be.</p>