java - Spring Boot集成测试中如何获取JPA上下文?

标签 java spring-boot jpa cucumber

我正在使用 jpa 运行 Springboot 应用程序。我正在尝试建立一个基于 Cucumber 的集成测试。当我在测试中尝试访问存储库时,我收到“org.hibernate.LazyInitializationException”(带有消息“No Session”)。这仅发生在我的集成测试中,但不会发生在实际应用程序中。解决方法是将 @Transactional 放在执行调用的方法上,但如果我在新线程中执行,这将不起作用。

我的第一个问题是:为什么没有 @Transactional 注释它就不起作用? 我的第二个问题是:为什么它不能在新线程中使用 @Transactional 注释?

这是我的代码的简化版本:

cucumber 测试:

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/some-integration-test.feature")
public class IntegrationTests {}

cucumber 步骤:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class IntegrationSteps {

    @Autowired
    SomeRepo repo;

    @When("two updates happen at the same time")
    public void twoUpdatesHappenAtTheSameTime() {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        executorService.execute(set("Thread 1"));

        executorService.execute(set("Thread 2"));

        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
    }

    public void set(String someThing) {
        Some some = repo.getOne(1234);
        repo.setSomeThing(someThing);
        repo.save(some);
    }
}

以及存储库:

@Repository
public interface SomeRepo extends JpaRepository<Some, Integer> {}

最佳答案

问题似乎出在 getOne() 上。使用getOne(),您只能获得对实体的引用。在尝试访问实体的字段之前,不会执行对数据库的真正调用。 通常,当使用 getOne() 时,这些字段会被延迟加载,但由于某种原因(我仍然不清楚),这在 SpringBootTest 中不起作用。

我找到了解决此问题的两种解决方案:

  1. 使用 @Transactional 注释测试。这样您将有一个加载实体的上下文。缺点是您似乎仍然没有获得实体的最新版本。就我而言,我更新了代码中的实体,而在测试代码中,实体中不存在更新(即使更新发生在 getOne() 调用之前)。
  2. 不要使用 getOne(),而是使用 findById()。缺点是 findById() 是急切加载的,但由于我们仅将其用于测试,因此它不会影响应用程序的性能。

关于java - Spring Boot集成测试中如何获取JPA上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59408874/

相关文章:

java - 如何使用 Springboot 在 REST 请求 URL 中将 json 对象作为参数传递

spring - 如何使用gradle任务将.yml转换为.properties?

jsf - 登录.xhtml : The requested resource is not available

java - 将多对多关系保存在相应的映射表中

java - hibernate 映射和未映射的类和 mysql 设计

java - 找到匹配的谓词。谓词的谓词?

spring-boot 默认的 EntityManager

java - 寻找方法来缩短文本对齐数组的代码

java - 如何在打开的 csv 中获取并验证 csv header ?

spring - 是什么导致了 "No property find found for type"spring数据jpa错误