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

Spring Boot Data JPA单表调用getById抛出LazyInitializationException异常

解决SpringBootTest中调用getById()抛出LazyInitializationException的问题

问题原因

Spring Data JPA的getById()方法默认返回Hibernate懒加载代理对象,它不会立即从数据库查询数据,而是在你第一次访问实体属性时才触发查询。如果此时代码已经脱离了事务上下文(比如测试方法未加@Transactional),Hibernate无法获取Session执行懒加载查询,就会抛出LazyInitializationException——哪怕你的实体没有任何关联字段,代理机制依然会生效。

解决方案

1. 改用findById()方法(推荐)

findById()会直接查询数据库并返回真实的实体对象(包装在Optional中),不会返回代理,从根源避免懒加载问题:

// 测试方法中调用
Optional<RequestsEntity> requestOpt = requestsRepository.findById("dummyId");
// 获取实体(如果存在)
RequestsEntity request = requestOpt.orElseThrow(() -> new RuntimeException("请求不存在"));

2. 在事务上下文内访问代理对象

如果一定要使用getById(),确保在@Transactional注解覆盖的代码块内访问实体的任意属性,触发数据加载:

@SpringBootTest
@Transactional
class RequestRepositoryTest {
    @Autowired
    private RequestsRepository requestsRepository;

    @Test
    void testGetById() {
        RequestsEntity proxy = requestsRepository.getById("dummyId");
        // 访问属性触发懒加载,此时在事务内不会报错
        System.out.println(proxy.getRequest());
    }
}

3. 关闭实体的懒加载代理(不推荐)

在实体类上添加@Proxy(lazy = false),强制Hibernate不生成代理对象,getById()会直接加载完整实体。但这种方式会降低性能,不建议生产环境使用:

@Data
@Entity
@Proxy(lazy = false) // 关闭懒加载代理
@Table(name = "REQUESTS", schema = "", catalog = "")
public class RequestsEntity {
    // 现有字段和构造方法
}

额外优化建议

  • 移除实体类上的@Component注解:JPA实体不需要被Spring作为Bean管理,该注解多余。
  • 移除Repository接口上的@Transactional注解:Spring Data JPA默认会为CRUD方法自动添加事务支持,手动添加无必要。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:49:54