Kotlin数据类继承+复制方法

时间:2017-11-16 01:34:39

标签: jpa inheritance kotlin

我从个人经验和this discussion都了解到,当data class继承自另一个继承了类的字段的类时,不会包含在数据类的copy函数中。

我对解决这个问题的方法感兴趣。

具体来说,我的JPA实体有一个JPA @MappedSuperClassdata class个。在超级类中,我设置了实体ID,至少到目前为止,我总是想以同样的方式进行操作。还有其他一些我可能想要做的事情,比如设置创建日期,上次更新日期等。

到目前为止我考虑的选项:

  1. 将ID,创建日期等复制粘贴到每个实体中。优点:它很简单,复制方法也适用。缺点:失败DRY,您无法使用共享超类处理所有实体。 (但可以为此创建一个界面。)

  2. 覆盖超类的值并将它们传递给超类。

  3. 您仍然需要将覆盖值复制粘贴到每个实体中,但至少您不必复制注释。

    @Entity
    data class Comment(
            @Lob
            comment: String,
    
            override val id: Long = -1
    ) : BaseEntity(id)
    
    @MappedSuperclass
    abstract class BaseEntity(
            @Id
            @GeneratedValue(strategy = GenerationType.AUTO)
            open val id: Long = -1
    )
    
    1. ???我甚至无法想到第三种选择。还有另一种方法吗?使ID成为var并且每次都创建自定义复制方法?这听起来很难看。

1 个答案:

答案 0 :(得分:1)

我非常确定,由于类型擦除,您将无法使用已定义的类的类型来完成此操作。因为您的data class正在扩展abstract class,所以您会遇到很多障碍。

同时实现这两种方法的最简单方法仍然需要一些工作,并且存在固有的缺点:

fun <T: BaseEntity> T.withBase(base: BaseEntity): T {
    id = base.id
    return this
}

这是一个简单的扩展方法,位于BaseEntity类定义的旁边,您只需在.copy()之后链接该调用即可。因此,您可以按以下方式使用它:

val base = Comment("Created an object")
val copy = base.copy().withBase(base)

注意事项:

  • 这将破坏您生成的值,因为copy()调用将实例化BaseEntity
  • 您必须记住将这些呼叫链接起来。

如果在复制时希望id递增(和任何@AutoGenerated值),则第一个警告将消失。但是,仍然需要链接,但是,链接确实可以大大减少复制/粘贴和其他可能的错误。