You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

getReferenceById是否为懒加载?为何测试未抛出预期异常?

原因分析与解决方案

核心原因

getReferenceById返回的是Hibernate代理对象,主键字段(比如id)是直接存储在代理实例中的,调用getId()时不需要触发懒加载去数据库查询,自然不会抛出LazyInitializationException。这是Hibernate代理的设计特性——创建代理时就会把主键值缓存下来,避免不必要的数据库交互。

验证懒加载的正确方式

要验证懒加载是否生效,需要访问实体的非主键属性(比如title、content这类需要从数据库读取的字段)。修改测试用例如下:

@Test
void whenGetUsedOutsideOfServiceThenThrowException() {
    Post post = postService.getReferenceById(EXISTING_ID);
    // 访问非主键属性,触发懒加载逻辑
    assertThatExceptionOfType(LazyInitializationException.class)
        .isThrownBy(post::getTitle);
}

运行修改后的测试用例,就能看到预期的LazyInitializationException异常了。

补充说明

  1. open-in-view: false的配置是生效的,它确实会在事务结束后关闭Hibernate会话,但这不影响代理对象中已缓存的主键值访问。
  2. Spring Boot 3.3.0搭配的Hibernate 6.x版本,在代理的主键处理逻辑上和旧版本保持一致,这个行为并非版本BUG。

内容的提问来源于stack exchange,提问作者Stephane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:28:21