正如 JPA 要求的那样,@Entity类应该有一个默认的(非参数)构造函数来在从数据库中检索对象时实例化它们。
@Entity
在 Kotlin 中,在主构造函数中声明属性非常方便,如下例所示:
class Person(val name: String, val age: Int) { /* ... */ }
但是当非参数构造函数被声明为辅助构造函数时,它需要传递主构造函数的值,因此它们需要一些有效值,如下所示:
@Entity class Person(val name: String, val age: Int) { private constructor(): this("", 0) }
如果属性有一些更复杂的类型String,Int并且它们是不可为空的,那么为它们提供值看起来非常糟糕,特别是当主构造函数和init块中有很多代码以及积极使用参数时 - - 当通过反射重新分配它们时,大部分代码将再次执行。
String
Int
init
而且,val-properties 不能在构造函数执行后重新赋值,所以也失去了不变性。
val
所以问题是:如何在不重复代码、选择“神奇”初始值和失去不变性的情况下使 Kotlin 代码适应 JPA 工作?
PS除了JPA之外的Hibernate真的可以构造没有默认构造函数的对象吗?
从 Kotlin 1.0.6 开始 ,kotlin-noarg编译器插件为已使用选定注释进行注释的类生成合成默认构造函数。
kotlin-noarg
如果您使用 gradle,则应用kotlin-jpa插件足以为带有注释的类生成默认构造函数@Entity:
kotlin-jpa
buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" } } apply plugin: "kotlin-jpa"
对于 Maven:
<plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <configuration> <compilerPlugins> <plugin>jpa</plugin> </compilerPlugins> </configuration> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-noarg</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies> </plugin>