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

集成Auditable的实体使用@PreUpdate注解触发StackOverflowError问题求解

问题根因

StackOverflow异常是@PreUpdate回调与数据库查询形成死循环导致:

  1. Hibernate执行实体更新前会触发@PreUpdate回调
  2. 回调方法中调用了tokenRegistryService、taxAdminSessionRepository的数据库查询逻辑
  3. Hibernate默认配置下,执行任何查询操作前会先flush当前持久化上下文的所有脏实体,flush过程又会再次触发@PreUpdate回调,无限循环最终导致栈溢出
    如果TokenRegistryEntity、TaxAdminSessionEntity本身也继承了集成@EntityListeners的Auditable父类,查询加载这些实体时会进一步触发回调,加重循环。
解决方案

方案1:查询时禁用自动flush(改造成本最低)

在相关Repository查询方法上添加QueryHint,设置FlushMode为COMMIT,避免查询前自动触发flush打断循环:

// TokenRegistryRepository 对应方法添加
@QueryHints(value = @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_FLUSH_MODE, value = "COMMIT"))
Optional<TokenRegistryEntity> findByUserIdAndStatus(Long userId, Status status);

// TaxAdminSessionRepository 对应方法添加
@QueryHints(value = @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_FLUSH_MODE, value = "COMMIT"))
Optional<TaxAdminSessionEntity> findByTokenAndUserIdAndAdminIdAndStatus(String token, Long userId, Long adminId, SessionStatus status);

方案2:将逻辑迁移到业务层(最符合规范)

JPA实体回调的设计定位是处理实体本身无外部依赖的字段赋值(如创建时间、更新时间),不适合在回调中执行数据库查询、依赖外部服务的逻辑:

  • 删掉实体类中@PrePersist、@PreUpdate的回调代码
  • 在业务层调用实体save/update操作前,先调用TaxAdminSessionServiceHelper.checkAdminSesstion()拿到结果,手动给实体的isBelongs字段赋值
    该方案彻底避免了回调内的数据库操作,无循环风险,后续可维护性更高。

方案3:添加重入检测避免循环

如果一定要保留回调逻辑,可以用ThreadLocal做重入标记,避免同一线程重复触发回调:

private static final ThreadLocal<Boolean> CALLBACK_RUNNING = ThreadLocal.withInitial(() -> false);

@PrePersist
protected final void belongTo(){
    if(CALLBACK_RUNNING.get()) return;
    try{
        CALLBACK_RUNNING.set(true);
        this.isBelongs= TaxAdminSessionServiceHelper.checkAdminSesstion();
    }finally {
        CALLBACK_RUNNING.remove();
    }
}

@PreUpdate
protected final void belongToUpdated(){
    if(CALLBACK_RUNNING.get()) return;
    try{
        CALLBACK_RUNNING.set(true);
        this.isBelongs= TaxAdminSessionServiceHelper.checkAdminSesstion();
    }finally {
        CALLBACK_RUNNING.remove();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:15:02