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

Spring Boot 3升级后JPA JOINED继承策略行为异常求助

Spring Boot 3.x 中JPA JOINED继承策略异常问题分析与解决

这不是Spring Boot 3的Bug,而是Hibernate版本升级(Spring Boot 3.x默认使用Hibernate 6.x,2.x版本使用Hibernate 5.x)带来的行为变化,核心问题出在Kotlin实体的属性覆盖处理逻辑上。

问题根源

你的ComputerBook作为Kotlin data class,显式覆盖了父类Book的id、author、publisher属性。在Hibernate 6.x中,这种显式覆盖会被识别为子类自身的独立字段,而非对父类字段的继承映射。查询时,父表的字段值会被注入到父类的属性中,子类覆盖的属性因为没有对应子类表的字段,所以返回null;而Hibernate 5.x会将这种覆盖视为对父类字段的重映射,因此表现出旧版本的结果。

解决方案

方案1:移除子类的属性覆盖(推荐)

父类属性已经标记为open,子类继承时无需重复声明,直接在构造函数中传递参数即可:

@Entity(name = "computer_book")
@DiscriminatorValue("computer")
data class ComputerBook @JvmOverloads constructor(
    val language: String,
    id: Long,
    author: String,
    publisher: String
) : Book(id, author, publisher)

如果需要满足JPA的无参构造要求,可调整构造函数定义:

@Entity(name = "computer_book")
@DiscriminatorValue("computer")
data class ComputerBook(
    val language: String,
    id: Long,
    author: String,
    publisher: String
) : Book(id, author, publisher) {
    @JvmOverloads constructor() : this("", 0, "", "")
}

方案2:显式指定属性映射

如果必须保留子类的属性覆盖,需要用@AttributeOverride注解明确绑定父表字段:

@Entity(name = "computer_book")
@DiscriminatorValue("computer")
data class ComputerBook @JvmOverloads constructor(
    @AttributeOverride(name = "id", column = Column(name = "id"))
    override var id: Long,
    @AttributeOverride(name = "author", column = Column(name = "author"))
    override var author: String,
    @AttributeOverride(name = "publisher", column = Column(name = "publisher"))
    override var publisher: String,
    var language: String
) : Book(id, author, publisher)

该注解会告诉Hibernate子类的覆盖属性对应父表的字段,避免被识别为子类表的独立字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:55:25