在 Kotlin 中使用 Jpa 注释从基类继承父属性

Posted

技术标签:

【中文标题】在 Kotlin 中使用 Jpa 注释从基类继承父属性【英文标题】:Inherit parent properties from a Base class with Jpa annotations in Kotlin 【发布时间】:2018-10-18 08:55:53 【问题描述】:

我们所有的 JPA 实体都有一个 @Id、@UpdateTimestamp、乐观锁定等...我的想法是创建某种基类,它包含每个 JPA 实体需要的所有东西,它们都可以继承。

open class JpaEntity (

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   var id : Long? = null,

   @UpdateTimestamp
   var lastUpdate : LocalDateTime? = null

   ...
)

我试图找到如何使用这个类(或任何其他解决方案),以便我们团队中的开发人员不需要一遍又一遍地重做相同的输入。

到目前为止,根据 JPA,我的实现没有“标识符”

@Entity
class Car (

    @get:NotEmpty
    @Column(unique = true)
    val name : String

) : JpaEntity()

有人对此有一个优雅的解决方案吗?

【问题讨论】:

【参考方案1】:

您可以按照我们在 Java 中执行此操作的相同方式为其他实体创建基类(例如 @MappedSuperclass):

@MappedSuperclass
abstract class BaseEntity<T>(
        @Id private val id: T
) : Persistable<T> 

    @Version
    private val version: Long? = null

    @field:CreationTimestamp
    val createdAt: Instant? = null

    @field:UpdateTimestamp
    val updatedAt: Instant? = null

    override fun getId(): T 
        return id
    

    override fun isNew(): Boolean 
        return version == null
    

    override fun toString(): String 
        return "BaseEntity(id=$id, version=$version, createdAt=$createdAt, updatedAt=$updatedAt, isNew=$isNew)"
    

    override fun equals(other: Any?): Boolean 
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        other as BaseEntity<*>
        if (id != other.id) return false
        return true
    

    override fun hashCode(): Int 
        return id?.hashCode() ?: 0
    

@Entity
data class Model(
        val value: String
) : BaseEntity<UUID>(UUID.randomUUID())  

    override fun toString(): String 
        return "Model(value=$value, $super.toString())"
    

查看我的工作example。

注意@field 注释 - 没有它,CreationTimestamp/UpdateTimestamp don't work。

【讨论】:

data class on Model 不是一个好方法,因为在 Kotlin 下会覆盖 BaseEntity equalshashCode 方法。而不是data class Model,您应该只使用class Model【参考方案2】:

您需要使用@Entity @Inheritance(strategy = ...)@MappedSuperclass 注释JpaEntity。对于您的情况,第二个似乎更合理,但请参阅documentation(或https://en.wikibooks.org/wiki/Java_Persistence/Inheritance)。

无论是 Kotlin(除了可能需要指定注解目标,如 get:)或使用 Spring Boot 都不应该有任何区别。

【讨论】:

以上是关于在 Kotlin 中使用 Jpa 注释从基类继承父属性的主要内容,如果未能解决你的问题,请参考以下文章

错误:与 'operator=' 不匹配。试图从基类继承并从基类初始化?

C++不能使用从基类继承的getter函数

将成员添加到从基类继承的结构

C++ - 让派生类从基类“继承”重载赋值运算符的安全/标准方法

Qt - 从基类继承一个类

从基类创建继承类