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

升级至Spring Boot 3.4.X后出现TransientObjectException问题求助

Spring Boot 3.4.0升级后删除关联实体触发TransientObjectException异常问题

问题描述

我的Spring Boot应用包含Catalog与CatalogCategory(关联表)两个实体,在Spring Boot 3.3.7版本中,以下代码可正常执行:

public void deepDelete(Category category) {

    //Catalog-category
    catalogCategoryService.deleteByCategory(category);

    delete(category);

}

但升级至Spring Boot 3.4.0后,出现如下TransientObjectException异常:

12T14:17:15.098+02:00 ERROR 26596 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: persistent instance references an unsaved transient instance of 'com.techi.gox.model.Category' (save the transient instance before flushing)] with root cause

org.hibernate.TransientObjectException: persistent instance references an unsaved transient instance of 'com.techi.gox.model.Category' (save the transient instance before flushing)
    at org.hibernate.engine.spi.CascadingActions$9.cascade(CascadingActions.java:382) ~[hibernate-core-6.6.2.Final.jar:6.6.2.Final]
    at org.hibernate.engine.spi.CascadingActions$9.cascade(CascadingActions.java:372) ~[hibernate-core-6.6.2.Final.jar:6.6.2.Final]

请问哪里操作有误?为何新版本会触发该异常?


问题原因

Spring Boot 3.4.0对应的Hibernate版本升级到了6.6.x,这个版本对实体关联的状态检查更严格。当前操作流程中,catalogCategoryService.deleteByCategory(category)执行后,Hibernate可能已将category实体的状态从持久化变为游离/瞬态;后续执行delete(category)时,Hibernate检测到该实体已脱离持久化上下文,而关联的CatalogCategory操作可能残留对它的引用,从而触发异常。

另外,也可能是实体关联配置(比如Catalog和CatalogCategory之间的级联关系)在新版本Hibernate下的行为变化导致——旧版本允许对游离实体执行删除,新版本则严格要求操作的实体必须处于持久化状态。

解决办法

  • 确保删除时Category处于持久化状态
    先通过ID重新加载Category实体,再执行删除操作,保证操作对象始终处于持久化上下文:

    public void deepDelete(Category category) {
        // 重新加载持久化状态的Category
        Category persistentCategory = categoryRepository.findById(category.getId()).orElseThrow();
        // 删除关联表记录
        catalogCategoryService.deleteByCategory(persistentCategory);
        // 删除持久化状态的实体
        delete(persistentCategory);
    }
    
  • 利用级联删除简化逻辑
    如果CatalogCategory和Category是多对一关联,可在Category的关联集合上配置级联删除,这样删除Category时会自动清理关联的CatalogCategory记录,无需手动调用删除方法:

    // 在Category实体中配置
    @OneToMany(mappedBy = "category", cascade = CascadeType.REMOVE)
    private List<CatalogCategory> catalogCategories;
    

    简化后的删除代码:

    public void deepDelete(Category category) {
        delete(category);
    }
    
  • 控制事务边界
    确保整个删除操作在同一个事务中执行,避免中间操作导致实体状态脱离持久化上下文。可在deepDelete方法上添加@Transactional注解:

    @Transactional
    public void deepDelete(Category category) {
        catalogCategoryService.deleteByCategory(category);
        delete(category);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:12:17