Spring Boot 3.1.0升级后Hibernate InstantiationException问题求助
问题重现
升级Spring Boot至3.1.0、替换javax为jakarta后,集成测试编译/运行时触发Hibernate实例化错误:
Caused by: org.springframework.orm.jpa.JpaSystemException: Unable to locate constructor for embeddable : com.example.nccn.aggregator.db.foo.FooEntityId
Caused by: org.hibernate.InstantiationException: Unable to locate constructor for embeddable : com.example.nccn.aggregator.db.foo.FooEntityId
同时伴随提示:
No default (no-argument) constructor for class: com.example.nccn.aggregator.db.foo.FooEntityId (class must be instantiated by Interceptor)
相关实体定义:
@Embeddable class FooEntityId( @Column(name = "id") var id: Long, ) : Serializable @Embeddable class FooFooEntityId( @Embedded var fooEntityId: FooEntityId, // 其他字段 ) : Serializable @Entity @Table(name = "foo_table", schema = "example") data class ExampleEntity( @EmbeddedId var id: FooFooEntityId? = null, // 其他字段 )
环境配置:
- Spring Boot 3.1.0
- Java 17
- Kotlin 1.7.0
- 已启用Kotlin插件:
-all-open、-spring、-no-args、-jpa,且反编译字节码确认无参构造函数已生成。
问题原因
Spring Boot 3.1.0适配的Hibernate 6.2.x版本对Kotlin Embeddable类的实例化逻辑做了调整,即使no-args插件生成了无参构造,Hibernate仍可能因构造函数可见性、嵌套Embeddable的初始化逻辑或插件注解覆盖范围问题无法识别。
解决方案
1. 显式添加无参次级构造函数
在所有Embeddable类中显式定义无参构造,直接指定默认值覆盖插件生成的构造:
@Embeddable class FooEntityId( @Column(name = "id") var id: Long, ) : Serializable { // 显式无参构造,指定默认值 constructor() : this(0L) } @Embeddable class FooFooEntityId( @Embedded var fooEntityId: FooEntityId, // 其他字段 ) : Serializable { constructor() : this(FooEntityId()) }
2. 调整Kotlin No-Args插件配置
确保no-args插件明确包含jakarta.persistence.Embeddable注解(升级后替换了javax),在build.gradle中补充配置:
plugins { id 'org.springframework.boot' version '3.1.0' id 'io.spring.dependency-management' version '1.1.0' id 'org.jetbrains.kotlin.jvm' version '1.7.0' id 'org.jetbrains.kotlin.plugin.spring' version '1.7.0' id 'org.jetbrains.kotlin.plugin.jpa' version '1.7.0' } kotlin { jvm { compilations.all { kotlinOptions { freeCompilerArgs += [ "-Xno-args=jakarta.persistence.Embeddable,jakarta.persistence.Entity" ] } } } }
3. 确保Hibernate Kotlin模块依赖
Spring Boot 3.1.0默认应该引入,但可显式声明确保版本匹配:
dependencies { implementation 'org.hibernate.orm:hibernate-core' implementation 'org.hibernate.orm:hibernate-kotlin' // 其他依赖 }
4. 调整嵌套Embeddable的字段默认值
给嵌套的Embeddable字段添加默认值,避免Hibernate初始化时遇到null:
@Embeddable class FooFooEntityId( @Embedded var fooEntityId: FooEntityId = FooEntityId(), // 其他字段 ) : Serializable
验证
修改后重新编译项目,运行集成测试,确认Hibernate实例化错误消失。
内容的提问来源于stack exchange,提问作者enccne

