title: Spring data jpa nested transaction rollback not deleting insert?
body: <p>I try to insert 2 records in my database in a transaction. The second insert fails but in the rollback the first insert is not deleted: </p>
  
  <pre><code>   @Resource
        private WebMessageRep rep; //&lt;-- extends JpaRepository
  
  @Transactional
    public void test() {
      WebMessage wm = new WebMessage(.valid params.);
      wm = rep.save(wm);//&lt;-- save is crud save which is transactional by default
      WebMessage wm2 = new WebMessage(.invalid params.);
      rep.save(wm2);
    }
  </code></pre>
  
  <p>(i also tried replacing the save method with:
  jpaContext.getEntityManagerByManagedType(WebMessage.class).persist(wm);
  so that i don't use the crud save, but the problem still exist)</p>
  
  <p>I enabled transaction logging to see what is going on, i discovered:</p>
  
  <p>Before calling test() a new transaction is created because @transactional annotaion:</p>
  
  <pre><code>Creating new transaction with name [com..data.webmessage.WebMessageServiceImpl.test]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
   Opened new EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
  </code></pre>
  
  <p>Calling first save, which sees the first transaction:</p>
  
  <pre><code>Found thread-bound EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
  </code></pre>
  
  <p>Second save sees also the first transaction:</p>
  
  <pre><code>Found thread-bound EntityManager [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com..shared.WebMessage#107]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=1} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
  2017-02-22 14:07:22,000 [           main] DEBUG orm.jpa.JpaTransactionManager             - Participating in existing transaction
  </code></pre>
  
  <p>When exiting test() a commit is done:</p>
  
  <pre><code> Committing JPA transaction on EntityManager [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com..shared.WebMessage#108], EntityKey[com..shared.WebMessage#107]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=2} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
  </code></pre>
  
  <p>It fails:</p>
  
  <pre><code>    Column 'text' cannot be null
   HHH000010: On release of batch it still contained JDBC statements
  HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
      Initiating transaction rollback after commit exception
  </code></pre>
  
  <p>Rolling back:</p>
  
  <pre><code>Rolling back JPA transaction on EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
  </code></pre>
  
  <p>The strange thing is that the first inserted record is still in my database (mysql). </p>
  
  <p>Not sure if it means anything but at commit we have:
  insertions=ExecutableList{size=2}
  but on rollback it is:
  insertions=ExecutableList{size=0}</p>
  
  <p>Does anybody know why it is not rolling back the first insert?</p>
  
  <p>My transaction config is quite simple:</p>
  
  <pre><code>&lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;
      &lt;property name="entityManagerFactory" ref="emf" /&gt;
  &lt;/bean&gt;
  
  &lt;tx:annotation-driven transaction-manager="transactionManager" /&gt;
  </code></pre>
  
  <p>Firing up my debugger revealed that my transaction is not active anymore when an rollback is attempted. Let me explain:</p>
  
  <p>[JpaTransactionManager.java]</p>
  
  <pre><code>@Override
      protected void doRollback(DefaultTransactionStatus status) {
          JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction();
          if (status.isDebug()) {
              logger.debug("Rolling back JPA transaction on EntityManager [" +
                      txObject.getEntityManagerHolder().getEntityManager() + "]");
          }
          try {
              EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction();
              if (tx.isActive()) {
                  tx.rollback();
              }
          }
          catch (PersistenceException ex) {
              throw new TransactionSystemException("Could not roll back JPA transaction", ex);
          }
          finally {
              if (!txObject.isNewEntityManagerHolder()) {
                  // Clear all pending inserts/updates/deletes in the EntityManager.
                  // Necessary for pre-bound EntityManagers, to avoid inconsistent state.
                  txObject.getEntityManagerHolder().getEntityManager().clear();
              }
          }
      }
  </code></pre>
  
  <p>The tx.isActive() in above code returns false, this means no rollback is executed.</p>
  
  <p>Now the big question is why is my transaction not active anymore?</p>