小编典典

带有 JPA 的 Kotlin:默认构造函数地狱

all

正如 JPA 要求的那样,@Entity类应该有一个默认的(非参数)构造函数来在从数据库中检索对象时实例化它们。

在 Kotlin 中,在主构造函数中声明属性非常方便,如下例所示:

class Person(val name: String, val age: Int) { /* ... */ }

但是当非参数构造函数被声明为辅助构造函数时,它需要传递主构造函数的值,因此它们需要一些有效值,如下所示:

@Entity
class Person(val name: String, val age: Int) {
    private constructor(): this("", 0)
}

如果属性有一些更复杂的类型StringInt并且它们是不可为空的,那么为它们提供值看起来非常糟糕,特别是当主构造函数和init块中有很多代码以及积极使用参数时
- - 当通过反射重新分配它们时,大部分代码将再次执行。

而且,val-properties 不能在构造函数执行后重新赋值,所以也失去了不变性。

所以问题是:如何在不重复代码、选择“神奇”初始值和失去不变性的情况下使 Kotlin 代码适应 JPA 工作?

PS除了JPA之外的Hibernate真的可以构造没有默认构造函数的对象吗?


阅读 77

收藏
2022-08-27

共1个答案

小编典典

从 Kotlin 1.0.6 开始kotlin-noarg编译器插件为已使用选定注释进行注释的类生成合成默认构造函数。

如果您使用 gradle,则应用kotlin-jpa插件足以为带有注释的类生成默认构造函数@Entity

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>
2022-08-27