title: Recalcitrant StaleObjectStateException problem using Spring Retry
body: <p>I am using Spring retry to handle retrying a given worker method in the case of unexpected minor errors.  Here is my simplified current code:</p>
  
  <pre><code>public class WorkerClass {
      @Autowired
      protected MyJpaRepository myJpaRepository;
  
      @Retryable(
          value = {Exception.class}, maxAttempts=3, backoff=@Backoff(5000))
      public void doSomething(RandomDTO dto) throws Exception {
          boolean success = false;
          try {
              // perform the task
              success = true;
          }
          catch (Exception e) {
              LOGGER.error("Something went wrong");
          }
  
          if (!success) {
              // create logEntity for failure using DTO
              MyEntity entity = myJpaRespository.save(logEntity);
              // update DTO using auto generated ID from entity
              throw new Exception("Give it another try!");
          }
          else {
              // create logEntity for success using DTO
              myJpaRespository.save(logEntity);
          }
      }
  
      @Recover
      public void recover(Exception ex, RandomDTO dto) {
          LOGGER.error("fatal error; all retries failed");
              // create logEntity for failure using DTO
          myJpaRespository.save(logEntity); // EXCEPTION OCCURS HERE
      }
  }
  </code></pre>
  
  <p>What I am observing is that the initial and all subsequent tries to the <code>doSomething()</code> method complete without error.  But, when the <code>recover()</code> method gets called, there is a JPA exception when trying to write to the repository.</p>
  
  <p>The stack trace contains:</p>
  
  <blockquote>
    <p>optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)</p>
  </blockquote>
  
  <p>My understanding of this problem is that Hibernate is, for some reason, maintaining a lock on the entity made in the <code>doSomething()</code> method.  Then, we the <code>recover()</code> method gets hit by the Spring retry framework, the update fails, because something else has a lock on that record.  But, I don't understand <em>why</em> this is happening.  Can someone shed light on this?</p>