title: Nested @Transactional methods with @Async
body: <p>I'm using Spring with JPA. I have <code>@EnableAsync</code> and <code>@EnableTransactionManagement</code> turned on. In my user registration service method, I have a few other service methods I call that are annotated <code>@Async</code>. These methods do various things like sending a welcome email and registering the newly minted user with our third party payment system.</p>
  
  <p>Everything works well until I want to verify that the third party payment system successfully created the user. At that point, the <code>@Async</code> method attempts to create a <code>UserAccount</code> (that references the newly minted <code>User</code>) and errors out with a <code>javax.persistence.EntityNotFoundException: Unable to find com.dk.st.model.User with id 2017</code></p>
  
  <p>The register call looks like this:</p>
  
  <pre><code>private User registerUser(User newUser, Boolean waitForAccount) {
      String username = newUser.getUsername();
      String email = newUser.getEmail();
  
      // ... Verify the user doesn't already exist
  
      // I have tried all manner of flushing and committing right here, nothing works
      newUser = userDAO.merge(newUser);
  
      // Here is where we register the new user with the payment system.
      // The User we just merged is not /actually/ in the DB
      Future&lt;Customer&gt; newCustomer = paymentService.initializeForNewUser(newUser);
      // Here is where I occasionally (in test methods) pause this thread to wait
      // for the successful account creation.
      if (waitForAccount) {
          try {
              newCustomer.get();
          } catch (Exception e) {
              logger.error("Exception while creating user account!", e);
          }
      }
  
      // Do some other things that may or may not be @Aysnc
  
      return newUser;
  }
  </code></pre>
  
  <p>The payment service calls out to do its work of registering the user and looks like this:</p>
  
  <pre><code>@Async
  @Override
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public Future&lt;Customer&gt; initializeForNewUser(User newUser) {
      // ... Set up customerParams
  
      Customer newCustomer = null;
      try {
          newCustomer = Customer.create(customerParams);
  
          UserAccount newAccount = new UserAccount();
          newAccount.setUser(newUser);
          newAccount.setCustomerId(newCustomer.getId());
          newAccount.setStatus(AccountStatus.PRE_TRIAL);
  
          // When merging, JPA cannot find the newUser object in the DB and complains
          userAccountDAO.merge(newAccount);
      } catch (Exception e) {
          logger.error("Error while creating UserAccount!", e);
          throw e;
      }
  
      return new AsyncResult&lt;Customer&gt;(newCustomer);
  }
  </code></pre>
  
  <p>The StackOverflow answer listed <a href="https://stackoverflow.com/questions/24338150/how-to-manually-force-a-commit-in-a-transactional-method">here</a> suggests that I set a <code>REQUIRES_NEW</code> propagation, which I have done, but with no such luck.</p>
  
  <p>Can anyone point me in the right direction? I really don't want to have to call the paymentService directly from my controller method. I feel that it should be a service level call for sure.</p>
  
  <p>Thanks for any help!</p>