带有默认值的Kotlin数据类上的Spring构造函数注释



为了在使用spring持久化的同时保持不可变类型,我在数据类中添加了PersistenceConstructor注释。这告诉spring在从数据库加载类时使用该构造函数。

然而,我有麻烦让春天找到构造函数。

data class MyData @PersistenceConstructor constructor(@Id val id: Int? = null, val a:String)

这在我的机器上100%工作,但当部署到heroku时,它总是失败。

看起来,通过为参数设置默认值,kotlin生成了多个构造函数,但问题是每个构造函数都得到了应用于它们的注释,所以哪个spring拾取只是运气(或特定于jdk实现)。默认的参数没有名称,所以Spring不知道该怎么处理它。

我真正的构造函数比这个大,所以没有默认值会很痛苦。是否有一种方法可以使注释仅应用于没有默认值的构造函数?

您可以使用@JvmOverloads注释,这将自动创建可以由Java调用的方法排列,并利用默认值。

从文档中,这个例子:

@JvmOverloads fun f(a: String, b: Int = 0, c: String = "abc") {
    ...
}

将在Java中被视为:

// Java
void f(String a, int b, String c) { }
void f(String a, int b) { } // will default c
void f(String a) { } // will default b and c

你的情况有点不同,你有一个默认参数后面跟着一个非默认参数。将示例简化为:

data class MyData @JvmOverloads constructor(val id: Int? = null, val a:String)

从Java生成如下视图:

// java
MyData(Int id, String a)
MyData(String a)  // defaults id

您可以在Kotlin参考中阅读有关Java调用Kotlin互操作性的更多信息。

目前我的答案是定义两个构造函数。一个是我用的,有默认值一个是spring用的,没有默认值。

data class MyData @PersistenceConstructor constructor(val a: Int?, val b:String, val c : Collection<Int>) {
  constructor(a: Int? = null, b: String = "", c: Collection<Int> = emptyList()) : this(a,b,c)
}

我不喜欢它的重复,所以它不是我的首选解决方案。

最新更新