Spring Native+Spring GraphQL中Kotlin数据类构造器异常排查
解决Spring Native + Spring GraphQL中Kotlin带默认参数类的构造器冲突问题
解决方案
方法1:把默认参数移到类成员属性中
修改数据类结构,将带默认值的参数从主构造器移出,改为类的成员属性:
data class UserListInput( val pageNumber: Int, val pageSize: Int, val keyword: String? ) { val sortBy: UserSortBy = UserSortBy.ID val sortDirection: SortDirection = SortDirection.ASCENDING }
这样主构造器只保留必填参数,Native编译时不会生成额外构造器,Spring GraphQL能正常解析传入的参数,未指定的字段会自动使用类属性的默认值。
方法2:用@ConstructorBinding指定主构造器
给数据类的主构造器添加@ConstructorBinding注解,明确告诉Spring使用该构造器:
import org.springframework.boot.context.properties.ConstructorBinding @ConstructorBinding data class UserListInput( val pageNumber: Int, val pageSize: Int, val sortBy: UserSortBy = UserSortBy.ID, val sortDirection: SortDirection = SortDirection.ASCENDING, val keyword: String? )
这个注解会让Spring忽略其他自动生成的构造器,只使用标注的主构造器进行参数绑定。
方法3:调整Kotlin编译配置限制构造器生成
在主构造器添加@JvmOverloads,同时修改编译参数减少额外构造器的生成:
data class UserListInput @JvmOverloads constructor( val pageNumber: Int, val pageSize: Int, val sortBy: UserSortBy = UserSortBy.ID, val sortDirection: SortDirection = SortDirection.ASCENDING, val keyword: String? = null )
在build.gradle.kts中添加Kotlin编译参数:
tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs += "-Xno-param-assertions" freeCompilerArgs += "-Xno-call-assertions" } }
这种方式相对繁琐,优先级低于前两种方法。
问题根源
Kotlin中带默认参数的类在GraalVM Native编译时,会自动生成一个包含kotlin.jvm.internal.DefaultConstructorMarker参数的额外构造器。Spring的BeanUtils.getResolvableConstructor方法无法识别唯一的有效构造器,因此抛出构造器找不到的异常。而无默认参数的数据类只会生成一个全参构造器,所以能正常工作。
内容的提问来源于stack exchange,提问作者Ken'ichi Ogawa
相关产品推荐
相关产品推荐

