hot*_*key 113 hibernate jpa default-constructor kotlin
正如JPA所要求的那样,@Entity类应该有一个默认(非arg)构造函数,用于在从数据库中检索对象时实例化对象.
在Kotlin中,在主构造函数中声明属性非常方便,如下例所示:
class Person(val name: String, val age: Int) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
但是当非arg构造函数被声明为次要构造函数时,它需要传递主构造函数的值,因此需要它们的一些有效值,如下所示:
@Entity
class Person(val name: String, val age: Int) {
private constructor(): this("", 0)
}
Run Code Online (Sandbox Code Playgroud)
在情况下,当性能有一些更复杂的类型不只是String和Int他们是不可为空的,它看起来完全坏为他们提供价值,尤其是当有在主构造和太多的代码init块,当这些参数都在积极使用- - 当他们通过反射重新分配时,大部分代码将再次执行.
此外,val在构造函数执行后,-properties不能重新分配,因此不可变性也会丢失.
所以问题是:Kotlin代码如何适应JPA而不需要代码重复,选择"神奇"的初始值和失去不变性?
PS除了JPA之外,Hibernate是否可以构造没有默认构造函数的对象?
Ing*_*gel 123
从Kotlin 1.0.6开始,kotlin-noarg编译器插件为已使用选定注释注释的类生成合成默认构造函数.
如果使用gradle,则应用kotlin-jpa插件足以为使用以下注释的类生成默认构造函数@Entity:
buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
}
}
apply plugin: "kotlin-jpa"
Run Code Online (Sandbox Code Playgroud)
对于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>
Run Code Online (Sandbox Code Playgroud)
小智 30
只需为所有参数提供默认值,Kotlin将为您创建默认构造函数.
@Entity
data class Person(val name: String="", val age: Int=0)
Run Code Online (Sandbox Code Playgroud)
请参阅NOTE以下部分下方的框:
https://kotlinlang.org/docs/reference/classes.html#secondary-constructors
@ D3xter对一个模型有很好的答案,另一个是Kotlin的新功能lateinit:
class Entity() {
constructor(name: String, age: Date): this() {
this.name = name
this.birthdate = age
}
lateinit var name: String
lateinit var birthdate: Date
}
Run Code Online (Sandbox Code Playgroud)
当您确定某些内容将在构造时或很快之后(以及在第一次使用实例之前)填充值时,您将使用此方法.
你会注意到我改为age,birthdate因为你不能使用原始值,lateinit它们目前也必须var(限制可能在将来发布).
因此,对于不变性而言,这不是一个完美的答案,在这方面与其他答案一样.解决方案是插件到库,可以处理理解Kotlin构造函数和将属性映射到构造函数参数,而不需要默认构造函数.杰克逊的Kotlin模块就是这样做的,所以显然是可能的.
另请参阅: https ://stackoverflow.com/a/34624907/3679676以了解类似选项.
在 gradle 中添加 JPA 插件对我有用:
plugins {
id("org.springframework.boot") version "2.3.4.RELEASE"
id("io.spring.dependency-management") version "1.0.10.RELEASE"
kotlin("jvm") version "1.3.72"
kotlin("plugin.spring") version "1.3.72"
kotlin("plugin.jpa") version "1.3.72"
}
Run Code Online (Sandbox Code Playgroud)
@Entity data class Person(/*@Id @GeneratedValue var id: Long? = null,*/
var name: String? = null,
var age: Int? = null)
Run Code Online (Sandbox Code Playgroud)
如果要为不同的字段重用构造函数,则需要初始值,kotlin不允许空值.因此,无论何时计划省略字段,请在构造函数中使用此表单:var field: Type? = defaultValue
jpa不需要参数构造函数:
val entity = Person() // Person(name=null, age=null)
Run Code Online (Sandbox Code Playgroud)
没有代码重复.如果您需要构造实体且仅设置年龄,请使用以下形式:
val entity = Person(age = 33) // Person(name=null, age=33)
Run Code Online (Sandbox Code Playgroud)
没有魔法(只是阅读文档)
小智 5
我自己就是一个小块头,但似乎您必须像这样显式初始化并回退到空值
@Entity
class Person(val name: String? = null, val age: Int? = null)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
37501 次 |
| 最近记录: |