title: How to use CompletableFuture.thenCompose() when returning entities from repositories?
body: <p>I started working with <code>CompletableFuture</code> in Spring Boot, and I'm seeing in some places that the usual repository methods return <code>CompletableFuture &lt;Entity&gt;</code> instead of <code>Entity</code>.</p>
  
  <p>I do not know what is happening, but when I return instances of <code>CompletableFuture</code> in repositories, the code runs perfectly. However when I return entities, the code does not work asynchronously and always returns <code>null</code>.</p>
  
  <p>Here is an example:</p>
  
  <pre><code>@Service
  public class AsyncServiceImpl{
      /** .. Init repository instances .. **/
  
      @Async(AsyncConfiguration.TASK_EXECUTOR_SERVICE)
      public CompletableFuture&lt;Token&gt; getTokenByUser(Credential credential) {
          return userRepository.getUser(credential)
              .thenCompose(s -&gt; TokenRepository.getToken(s));
      }
  }
  
  @Repository
  public class UserRepository {
  
      @Async(AsyncConfiguration.TASK_EXECUTOR_REPOSITORY)
      public CompletableFuture&lt;User&gt; getUser(Credential credentials) {
          return CompletableFuture.supplyAsync(() -&gt; 
              new User(credentials.getUsername())
          );
      }       
  }
  
  @Repository
  public class TokenRepository {
  
      @Async(AsyncConfiguration.TASK_EXECUTOR_REPOSITORY)
      public CompletableFuture&lt;Token&gt; getToken(User user) {
          return CompletableFuture.supplyAsync(() -&gt; 
              new Token(user.getUserId())
          );
      }
  }
  </code></pre>
  
  <p>The previous code runs perfectly but the following code doesn't run asynchronously and the result is always <code>null</code>.</p>
  
  <pre><code>@Service
  public class AsyncServiceImpl {
      /** .. Init repository instances .. **/
  
      @Async(AsyncConfiguration.TASK_EXECUTOR_SERVICE)
      public CompletableFuture&lt;Token&gt; requestToken(Credential credential) {
          return CompletableFuture.supplyAsync(() -&gt; userRepository.getUser(credential))
              .thenCompose(s -&gt; 
                  CompletableFuture.supplyAsync(() -&gt; TokenRepository.getToken(s)));
      }
  }
  
  @Repository
  public class UserRepository {
      @Async(AsyncConfiguration.TASK_EXECUTOR_REPOSITORY)
      public User getUser(Credential credentials) {
          return new User(credentials.getUsername());
      }       
  }
  
  @Repository
  public class TokenRepository {
      @Async(AsyncConfiguration.TASK_EXECUTOR_SERVICE)
      public Token getToken(User user) {
          return new Token(user.getUserId());
      }
  }
  </code></pre>
  
  <p>Why doesn't this second code work?</p>