Kotlin与JPA:默认构造函数hell [英] Kotlin with JPA: default constructor hell

查看:145
本文介绍了Kotlin与JPA:默认构造函数hell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

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

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

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

如果属性的复杂类型比 String Int 并且它们是不可为空的,但为它们提供值看起来非常糟糕,特别是当代码很多时主要con structor和 init 块,当参数被主动使用时 - 当它们要通过反射重新分配时,大部分代码将被再次执行。



此外, val -properties不能在构造函数执行后重新分配,所以不可变性也会丢失。



所以问题是:Kotlin代码如何适应与JPA一起工作而没有代码重复,选择魔术初始值和不可变性?

PS除了JPA,Hibernate是否可以构造没有默认构造函数的对象?

解决方案

自Kotlin 1.0.6 kotlin-noarg 编译器插件会为使用选定注释注解的类生成合成默认构造函数。



如果使用gradle,应用 kotlin-jpa 插件足以为使用 @Entity

  buildscript {
dependencies {
classpathorg.jetbrains.kotlin:kotlin-noarg :$ kotlin_version

}

应用插件:kotlin-jpa

对于Maven:

 < plugin> 
< artifactId> kotlin-maven-plugin< / artifactId>
< groupId> org.jetbrains.kotlin< / groupId>
< version> $ {kotlin.version}< / version>

<配置>
< compilerPlugins>
< plugin> jpa< / plugin>
< / compilerPlugins>
< / configuration>

<依赖关系>
< dependency>
< groupId> org.jetbrains.kotlin< / groupId>
< artifactId> kotlin-maven-noarg< / artifactId>
< version> $ {kotlin.version}< / version>
< /依赖关系>
< /依赖关系>
< / plugin>


As JPA requires, @Entity classes should have a default (non-arg) constructor to instantiate the objects when retrieving them from the database.

In Kotlin, properties are very convenient to declare within the primary constructor, as in the following example:

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

But when the non-arg constructor is declared as a secondary one it requires values for the primary constructor to be passed, so some valid values are needed for them, like here:

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

In case when the properties have some more complex type than just String and Int and they're non-nullable, it looks totally bad to provide the values for them, especially when there's much code in primary constructor and init blocks and when the parameters are actively used -- when they're to be reassigned through reflection most of the code is going to be executed again.

Moreover, val-properties cannot be reassigned after the constructor executes, so immutability is also lost.

So the question is: how can Kotlin code be adapted to work with JPA without code duplication, choosing "magic" initial values and loss of immutability?

P.S. Is it true that Hibernate aside of JPA can construct objects with no default constructor?

解决方案

As of Kotlin 1.0.6, the kotlin-noarg compiler plugin generates synthetic default construtors for classes that have been annotated with selected annotations.

If you use gradle, applying the kotlin-jpa plugin is enough to generate default constructors for classes annotated with @Entity:

buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
    }
}

apply plugin: "kotlin-jpa"

For 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>

这篇关于Kotlin与JPA:默认构造函数hell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆