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

Spring Boot中@LastModifiedBy用User类型触发StackOverflowError问题

问题背景

最初在Spring Boot应用中,Book实体类的@LastModifiedBy字段为String类型时,JPA审计功能正常工作,相关代码如下:

Book实体类

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Book {

    @Id
    private Long id;

    private String title;

    @LastModifiedDate
    private LocalDateTime lastModified;

    @LastModifiedBy
    private String lastModifiedBy;

}

JpaAuditingConfig配置类

@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class JpaAuditingConfig {

    private final AuthService authService;

    public JpaAuditingConfig(AuthService authService) {
        this.authService= authService;
    }

    @Bean
    public AuditorAware<String> auditorProvider() {
        return () -> Optional.ofNullable(authService.getUsername());
    }

}

AuthService类

@Service
public class AuthService {

    private final UserService userService;

    public String getUsername() {
        return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }

    public User getUser() {
        return this.userService.getByUsername(this.getUsername());
    }
}

当将@LastModifiedBy字段改为User类型,并修改auditorProvider返回AuditorAware<User>后,保存Book实体时出现StackOverflowError,报错信息如下:

*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at s\src\java.instrument\share\native\libinstrument\JPLISAgent.c line: 884
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction

Caused by: jakarta.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:67)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:561)
    ... 115 more
Caused by: java.lang.RuntimeException: java.lang.StackOverflowError
栈溢出原因分析

核心原因是实体双向关联引发的无限递归加载:

  • 当@LastModifiedBy改为User类型后,Book与User形成了关联关系,若User实体中同时存在关联Book的集合字段(比如List<Book> books),就构成了双向关联。
  • 事务提交时,Hibernate会对持久化上下文做脏检查:遍历User对象时会加载其关联的Book集合,遍历Book对象时又会加载其关联的User实例,如此循环往复,调用栈不断加深,最终触发StackOverflowError。
  • 另一种可能是AuthService.getUser()获取User实例时,触发了额外的级联操作或循环依赖,但最常见的诱因还是双向关联未做递归阻断处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 05:38:25