Kotlin数据类上的Spring构造函数注解,具有默认值

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

但是,我很难找到构造函数的春天。

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

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

看起来,通过具有参数默认值kotlin生成多个构造函数,但问题是,每个构造函数都得到应用于它们的注释,所以它只是运气(或特定的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互操作性的更多信息。

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

 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) } 

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