Search code examples
java-8completable-future

CompletableFuture to make multiple DB calls and get the response back


How to make Async call to DB and save the details and get the response entity back? Assume I am hitting to two different Data Centers. How can I get the entity back as response?

CompletableFuture.supplyAsync(() -> abcDc1Repository.save(localEntity));
CompletableFuture.supplyAsync(() -> abcDc2Repository.save(localEntity));

Solution

  • You can use CompletableFuture.allOf()

        CompletableFuture<OrderEntity> firstFuture = CompletableFuture.supplyAsync(
                () -> firstRepository.save(firstEntity)
        );
        CompletableFuture<OrderEntity> secondFuture = CompletableFuture.supplyAsync(
                () -> secondRepository.save(secondEntity)
        );
    
        CompletableFuture.allOf(firstFuture, secondFuture).join();
    
        OrderEntity firstEntity = firstFuture.get();
        OrderEntity secondEntity = secondFuture.get();
    

    You don't need a result, if you save new entity. Hibernate will set id to the passed entity.

    From SimpleJpaRepository

        @Transactional
        @Override
        public <S extends T> S save(S entity) {
            if (entityInformation.isNew(entity)) {
                em.persist(entity);
                return entity;
            } else {
                return em.merge(entity);
            }
        }
    

    Notes

    Keep in mind that CompletableFuture.supplyAsync() uses common fork-join pool. So your operation will wait for stream.parallel() operations in any point of the application.

    Also you shouldn't have a common transaction (a persistent context, with @Transactional) for these two calls, because persistent context is not thread safe.