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

排查Hibernate 6中“无法确定推荐JdbcType”异常的原因

Hibernate 6中@Embeddable类@Transient反向引用引发JdbcTypeRecommendationException的解决办法

问题现象

将Spring Boot从2.7.x(对应Hibernate 5)升级到3.2.3(对应Hibernate 6)后,包含以下代码的应用抛出JdbcTypeRecommendationException异常:

Could not determine recommended JdbcType for Java type...

@Entity(name = "JobGroup")
public class JobGroupEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @ElementCollection
    private List<JobReference> jobs = new ArrayList<>();
}

@Embeddable
public class JobReference {
    private String jobId;

    @Transient
    private JobGroupEntity jobGroup;
}

移除JobReference中的jobGroup字段后异常消失,即使移除@Transient注解或添加@JdbcTypeCode注解也无法解决问题。

原因分析

Hibernate 5的处理逻辑

在Hibernate 5中,@Embeddable类中标注@Transient的字段会被完全忽略,不会参与任何映射元数据的收集和类型解析流程,因此这类实体类型的反向引用不会触发任何映射相关的校验。

Hibernate 6的变更

Hibernate 6对元数据收集和类型校验机制做了大幅调整:

  1. 注解兼容性:Spring Boot 3基于Jakarta EE API,Hibernate 6仅识别jakarta.persistence.Transient注解,若仍使用旧的javax.persistence.Transient,注解会失效,Hibernate会将该字段视为需要映射的字段。
  2. 元数据校验增强:即使使用了正确的@Transient注解,当字段类型为实体类时,Hibernate的类型解析器仍会尝试解析该类型的JDBC映射规则,尤其在@ElementCollection关联场景下,这种校验会触发异常。

解决方案

1. 替换为Jakarta版本的@Transient注解

确保JobReference中的@Transient来自jakarta.persistence包,而非旧的javax.persistence:

import jakarta.persistence.Transient;

@Embeddable
public class JobReference {
    private String jobId;

    @Transient
    private JobGroupEntity jobGroup;
}

2. 结合@Access注解明确访问方式

如果替换注解后仍有问题,可通过@Access强制Hibernate通过属性访问而非字段访问,从而忽略该字段的映射:

import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.Transient;

@Embeddable
public class JobReference {
    private String jobId;

    @Transient
    @Access(AccessType.PROPERTY)
    private JobGroupEntity jobGroup;

    // 必须添加getter和setter
    public JobGroupEntity getJobGroup() {
        return jobGroup;
    }

    public void setJobGroup(JobGroupEntity jobGroup) {
        this.jobGroup = jobGroup;
    }
}

3. 字段初始化方式调整(可选)

如果仅需在内存中维护反向引用,可直接在构造方法或业务逻辑中初始化该字段,避免Hibernate的元数据解析触发异常:

@Embeddable
public class JobReference {
    private String jobId;
    private JobGroupEntity jobGroup;

    // 构造方法中初始化,或通过业务方法设置,不依赖Hibernate映射
    public JobReference() {
        this.jobGroup = null;
    }

    // 仅提供业务层面的getter/setter,不添加任何JPA注解
    public JobGroupEntity getJobGroup() {
        return jobGroup;
    }

    public void setJobGroup(JobGroupEntity jobGroup) {
        this.jobGroup = jobGroup;
    }
}

内容的提问来源于stack exchange,提问作者E-Riz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 18:26:01