![](/img/trans.png)
[英]Enable hibernate filter globally with spring-boot & spring-data
[英]LazyInitializationException in unit tests under Spring-Data/Spring-Boot
我的单元测试看到org.hibernate.LazyInitializationException: could not initialize proxy [org.openapitools.entity.MenuItem#5] - no Session
。 我不确定他们为什么希望在单元测试中使用 session。 我正在尝试写入内存中的 h2 数据库,以对实现 RESTful API 的 Controller 类进行单元测试。 我没有使用任何模拟对象进行测试,因为我想测试实际的数据库事务。 这在我使用 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 使用延迟加载来避免从数据库中加载整个 object 图。 如果您关闭 session 或连接到数据库,例如通过结束事务,Hibernate 不能再延迟加载,显然,您的代码会尝试访问需要延迟加载的 state。
您可以在存储库上使用@EntityGraph
来指定应获取关联,或者避免访问未在事务之外初始化的 state。 也许您只需要通过将@Transactional
放在调用存储库并访问state 的方法上来扩大事务scope,以便延迟加载工作。
我找到了解决这个问题的方法。 我不确定这是否是最好的方法,所以如果有人有更好的想法,我会很高兴收到他们的来信。
这就是我所做的。 首先,在从延迟加载的实体中读取值之前,我调用Hibernate.initialize(item);
这会引发相同的异常。 但是现在我可以在 application.properties 的测试版本中添加一个属性,上面写着
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
现在初始化方法将起作用。
PS 我还没有找到像这样的 Spring 属性的良好参考。 如果有人知道我在哪里可以看到可用的属性,我很想听听。 Spring 的人员在记录这些属性方面做得不是很好。 即使他们提到了一个特定的属性,他们也没有提供一个可以更彻底地解释它的链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.