简体   繁体   English

Spring Data JPA-返回未来

[英]Spring Data JPA - return Future

I tried to save my entity asynchronous and return future of the result, but I had following problems: 我试图保存我的实体异步并返回结果的未来,但是我遇到以下问题:

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);
    }

Test returns Failed and I get expected:<CountryEntity(id=1, code=EN)> but was:<null> 测试返回失败,并且我得到了expected:<CountryEntity(id=1, code=EN)> but was:<null>

How can I implement my repository as asynchronous repository and how to test it? 如何将我的存储库实现为异步存储库以及如何对其进行测试?

Which approach has better performance: 1. return Futures from repository 2. run repository methods as Callable in ExecutorService ? 哪种方法具有更好的性能:1.从存储库返回期货2.在ExecutorService中以Callable的身份运行存储库方法?

If you use @Async the repository code runs in a separate thread within it's own transaction. 如果使用@Async则存储库代码将在其自身事务中的单独线程中运行。 Since your original transaction isn't committed, it won't see the changes (ie the inserted entity) hence the null result. 由于您的原始交易未提交,因此看不到更改(即插入的实体),因此结果为null

So in order to make it work, you need to commit the first transaction. 因此,为了使其正常工作,您需要提交第一笔交易。

Regarding the second question about the performance (Please make separate questions next time): Performance of multithreaded code depends on so many things that really the only useful way to answer it: try it. 关于性能的第二个问题(下次请另外回答):多线程代码的性能取决于很多事情,这实际上是回答它的唯一有用方法:尝试一下。 But I would be surprised if the way how you schedule the execution has more effect on the performance than things like thread pool and connection pool size. 但是,如果安排执行的方式对性能的影响比对线程池和连接池大小的影响更大,我会感到惊讶。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM