Spring Data JPA - 返回 Future

标签 spring multithreading spring-data future completable-future

我尝试异步保存我的实体并返回结果的 future ,但遇到以下问题:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.Repository;
import org.springframework.scheduling.annotation.Async;
//import org.springframework.stereotype.Repository;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

// I must extend Repository because when I extended JpaRepository an argument 
// of save is ambigous when I try save(countryEntity) - compiler shows me 
// save (CountryEntity) in AsyncCountryRepository and save (S) in CrudRepository
public interface AsyncCountryRepository extends Repository<CountryEntity, Long> {

    // I don't know why I cannot return Future<CountryEntity>
    @Async
    <S extends CountryEntity> Future<S> save(CountryEntity countryEntity);

    // I cannot test it - test is below
    @Async
    CompletableFuture<CountryEntity> findByCode(String code);

}


@RunWith(SpringRunner.class)
@DataJpaTest
public class CountryRepositoryTest {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private AsyncCountryRepository countryRepository;

    @Test
    public void findByCodeTest() throws Exception {
        // given
        final CountryEntity countryEntity = new CountryEntity("EN");

        final CountryEntity persisted = entityManager.persist(countryEntity);
        entityManager.flush();

        // when
        final Future<CountryEntity> byCode = countryRepository.findByCode(persisted.getCode());

        // then
        assertThat(byCode.get())
                .isEqualTo(persisted);
    }

测试返回失败,我得到 expected:<CountryEntity(id=1, code=EN)> but was:<null>

如何将我的存储库实现为异步存储库以及如何测试它?

哪种方法具有更好的性能: 1.从存储库返回Futures 2. 在 ExecutorService 中将存储库方法作为 Callable 运行 ?

最佳答案

如果您使用@Async,存储库代码将在其自己的事务内的单独线程中运行。由于您的原始事务未提交,因此它不会看到更改(即插入的实体),因此结果为 null

因此,为了使其正常工作,您需要提交第一个事务。

关于关于性能的第二个问题(请下次单独提出问题):多线程代码的性能取决于很多因素,因此唯一有用的回答方法是:尝试一下。但如果安排执行的方式比线程池和连接池大小等对性能的影响更大,我会感到惊讶。

关于Spring Data JPA - 返回 Future,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46548804/

相关文章:

java - @RequestParam 接收到的加号(+)被替换为空白

ruby-on-rails - Ruby 中的线程会提高并发性吗?

windows - 跨线程的数值差异(cygwin 上的 openMP)

java - Spring 数据 : JPA Repository in abstract base service to call findAll with specification

java - 为什么我们必须使用 @Modifying 注解在 Data Jpa 中进行查询

Spring:绑定(bind)到命令时转义输入

java - 我应该如何验证 Spring Rest API 中 @requestparam 中的依赖参数?

node.js - Node.js 中是否可以同时从两个线程写入文件?

angularjs - spring Boot 和 Angular JS : what is the best way to deal with the authentication?

spring - jpa :repositories tag?的Java配置版本是多少