按照JPA的要求,@Entity类应具有默认的(非arg)构造函数,以在从数据库中检索对象时实例化这些对象。
@Entity
在Kotlin中,可以很方便地在主构造函数中声明属性,如以下示例所示:
class Person(val name: String, val age: Int) { /* ... */ }
但是,当将非arg构造函数声明为辅助构造函数时,它要求传递主要构造函数的值,因此需要一些有效值,例如:
@Entity class Person(val name: String, val age: Int) { private constructor(): this("", 0) }
如果属性的类型比just更复杂String,Int并且它们不能为null,那么为它们提供值看起来是非常糟糕的,尤其是当主要构造函数和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>