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

Lio*_*ort 4 spring kotlin

要使用spring持久性但保持不可变类型,我已将PersistenceConstructor注释添加到我的数据类中.这告诉spring在从数据库加载类时使用该构造函数.

但是,我在找到构造函数时遇到问题.

data class MyData @PersistenceConstructor constructor(@Id val id: Int? = null, val a:String)
Run Code Online (Sandbox Code Playgroud)

这在我的机器上100%的时间工作,但是当部署到heroku时它始终失败.

看起来,通过让参数kotlin的默认值生成多个构造函数,问题是每个构造函数都会获得应用于它们的注释,因此它只是运气(或特定于jdk实现),这是一个春天选择的.默认的参数没有名称,因此Spring不知道如何处理它.

我真正的构造函数比这个大,所以没有默认值会很痛苦.有没有办法让注释只应用于没有默认值的构造函数?

Jay*_*ard 8

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

从文档中,这个例子:

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

将从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
Run Code Online (Sandbox Code Playgroud)

如果您有一个默认参数,后跟一个不是默认参数,那么您的情况会有所不同.将您的示例简化为:

data class MyData @JvmOverloads constructor(val id: Int? = null, val a:String)
Run Code Online (Sandbox Code Playgroud)

从Java生成此视图:

// java
MyData(Int id, String a)
MyData(String a)  // defaults id
Run Code Online (Sandbox Code Playgroud)

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


Lio*_*ort 5

目前我当前的答案是定义两个构造函数。一种供我使用,有默认值,另一种供 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)
}
Run Code Online (Sandbox Code Playgroud)

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