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
相关产品推荐
相关产品推荐

