java - Spring-Data/Spring-Boot 下单元测试中的 LazyInitializationException
问题描述
我的单元测试正在查看org.hibernate.LazyInitializationException: could not initialize proxy [org.openapitools.entity.MenuItem#5] - no Session
。我不确定他们为什么希望在单元测试中进行会话。我正在尝试为实现 RESTful API 的 Controller 类的单元测试写入内存中的 h2 数据库。我没有使用任何模拟对象进行测试,因为我想测试实际的数据库事务。这在我使用 Spring-Boot 版本 1.x 时效果很好,但在我移到版本 2 时就坏了。(我不确定这是否是导致测试中断的原因,因为我做了很多其他更改。我的观点是我的代码已经通过了这些测试。)
我的存储库扩展了 JPARepository,所以我使用标准的 Hibernate 接口。
StackOverflow 上有很多关于这个问题的答案,但很少有人描述我可以与 Spring-Data 一起使用的解决方案。
附录:下面看一下单元测试:
@Test
public void testDeleteOption() throws ResponseException {
MenuItemDto menuItemDto = createPizzaMenuItem();
ResponseEntity<CreatedResponse> responseEntity
= adminApiController.addMenuItem(menuItemDto);
final CreatedResponse body = responseEntity.getBody();
assertNotNull(body);
Integer id = body.getId();
MenuItem item = menuItemApiController.getMenuItemTestOnly(id);
// Hibernate.initialize(item); // attempted fix blows up
List<String> nameList = new LinkedList<>();
for (MenuItemOption option : item.getAllowedOptions()) { // blows up here
nameList.add(option.getName());
}
assertThat(nameList, hasItems("pepperoni", "olives", "onions"));
// ... (more code)
}
我的测试 application.properties 有这些设置
spring.datasource.url=jdbc:h2:mem:pizzaChallenge;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=pizza
spring.datasource.password=pizza
spring.jpa.show-sql=true
解决方案
这不是标准的 Hibernate,而是 spring 数据。您必须了解 Hibernate 使用延迟加载来避免从数据库中加载整个对象图。如果您关闭会话或与数据库的连接,例如通过结束事务,Hibernate 不能再延迟加载,显然,您的代码会尝试访问需要延迟加载的状态。
您可以@EntityGraph
在存储库上使用来指定应获取关联,或者避免访问未在事务之外初始化的状态。或许你只需要放上@Transactional
调用仓库和访问状态的方法来扩大事务范围,这样延迟加载就可以工作了。
推荐阅读
- android - 发现人工制品的本机依赖项
- next.js - 使用 Netlify 部署 Next.js 网站
- c# - HttpContent.ReadAsStringAsync 导致请求挂起
- cordova - 如何使用适用于 Apache Cordova 的 cordova-android 定位最广泛的 Android 设备?
- java - 如何检查android studio中的日期是否更改?
- math - 如何从两个 3D 方向向量中获得 X 和 Y 旋转(零 Z 旋转)
- c - 不能在 C 中的 main() 之前声明 void 函数
- javascript - 具有单击功能的 addEventListener 不起作用
- botframework - 如何获取已发送消息 Bot Framework(团队频道)的消息 ID?
- jquery - 使菜单下拉集中在可访问性上