错误:惰性类的 Getter 不能是最终的 Kotlin Spring Boot

Posted

技术标签:

【中文标题】错误:惰性类的 Getter 不能是最终的 Kotlin Spring Boot【英文标题】:Error: Getters of lazy classes cannot be final Kotlin Spring Boot 【发布时间】:2020-04-29 10:38:40 【问题描述】:

我尝试在 Kotlin 上创建 REST Spring Boot Server。我使用了数据库 - 首先是使用内置 Intellij 工具自动生成的实体。启动服务器时弹出错误:

2020-01-12 15:09:14.387 ERROR 23016 --- [  restartedMain] o.h.tuple.entity.PojoEntityTuplizer      : HHH000112: Getters of lazy classes cannot be final: ru.madbrains.smartfridgemanager.server.model.MealplanEntity.name
2020-01-12 15:09:14.391 ERROR 23016 --- [  restartedMain] o.h.tuple.entity.PojoEntityTuplizer      : HHH000243: Setters of lazy classes cannot be final: ru.madbrains.smartfridgemanager.server.model.MealplanEntity.name
2020-01-12 15:09:14.391 ERROR 23016 --- [  restartedMain] o.h.tuple.entity.PojoEntityTuplizer      : HHH000112: Getters of lazy classes cannot be final: ru.madbrains.smartfridgemanager.server.model.MealplanEntity.refRecipeEntities
2020-01-12 15:09:14.391 ERROR 23016 --- [  restartedMain] o.h.tuple.entity.PojoEntityTuplizer      : HHH000243: Setters of lazy classes cannot be final: ru.madbrains.smartfridgemanager.server.model.MealplanEntity.refRecipeEntities

我的实体:

import javax.persistence.*

@Entity
@Table(name = "mealplan", schema = "public", catalog = "smartfridgemanagerdatabase")
open class MealplanEntity 
    @get:Id
    @get:Column(name = "id", nullable = false, insertable = false, updatable = false)
    var id: Int? = null
    @get:Basic
    @get:Column(name = "name", nullable = true)
    var name: Int? = null

    @get:OneToMany(mappedBy = "refMealplanEntity")
    var refRecipeEntities: List<RecipeEntity>? = null

    override fun toString(): String =
            "Entity of type: $javaClass.name ( " +
                    "id = $id " +
                    "name = $name " +
                    ")"

    // constant value returned to avoid entity inequality to itself before and after it's update/merge
    override fun hashCode(): Int = 42

    override fun equals(other: Any?): Boolean 
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        other as MealplanEntity

        if (id != other.id) return false
        if (name != other.name) return false

        return true
    

怎么了?

编辑 1:我的 build.gradle.kts 文件: (使用 Spring Initializr - start.spring.io 生成)

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins 
    id("org.springframework.boot") version "2.2.2.RELEASE"
    id("io.spring.dependency-management") version "1.0.8.RELEASE"
    kotlin("jvm") version "1.3.61"
    kotlin("plugin.spring") version "1.3.61"
    kotlin("plugin.jpa") version "1.3.61"


group = "ru.madbrains.smartfridgemanager"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8

val developmentOnly by configurations.creating
configurations 
    runtimeClasspath 
        extendsFrom(developmentOnly)
    


repositories 
    mavenCentral()


dependencies 
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.0.RELEASE")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.postgresql:postgresql")
    implementation("io.jsonwebtoken:jjwt:0.9.1")
    developmentOnly("org.springframework.boot:spring-boot-devtools")


tasks.withType<KotlinCompile> 
    kotlinOptions 
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    

【问题讨论】:

您是否使用 start.spring.io 生成了构建文件(pom.xml 或 build.gradle)?如果没有,请执行此操作,您将应用相应的插件。 @JBNizet,是的,我用 start.spring.io 生成了它 配置 allopen 插件以包含带有@Entity注解的类 【参考方案1】:

open 属性添加到属性为我解决了这个问题。比如

open var name: Int? = null

【讨论】:

我也从注释中删除了“@get:”【参考方案2】:

扩展 JB Nizets 评论以配置 all-open 插件。

如果您使用全开放插件,您可以通过添加pluginOptions 部分使其包含您的实体类:

<plugin>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-plugin</artifactId>
    <configuration>
        <compilerPlugins>
            <plugin>all-open</plugin>
        </compilerPlugins>

        <pluginOptions>
            <option>all-open:annotation=javax.persistence.Entity</option>
        </pluginOptions>
    </configuration>
</plugin>

这将使全开放插件处理所有带有 JPA @Entity 注释的类,以便它们(以及它们的函数)将变为非最终的。

【讨论】:

以上是关于错误:惰性类的 Getter 不能是最终的 Kotlin Spring Boot的主要内容,如果未能解决你的问题,请参考以下文章

惰性求值和 const 正确性问题

c ++防止通过getter更改引用

使用 CoreData,如果我有一个 @dynamic 属性,我可以像 @synthesized 一样覆盖它的 getter 吗? (惰性实例化)

惰性 var 给出“实例成员不能用于类型”错误

在不调用属性的情况下获取休眠惰性关系 n+1 - Kotlin

kotlin学习总结——类和对象继承接口和抽象类