Kotlin数据类继承+复制方法

Cor*_*han 7 inheritance jpa kotlin

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

我对解决此问题的选择感兴趣。

具体来说,我@MappedSuperClass为我的JPA实体有一个JPA data class。在超类中,我设置了实体ID,至少到目前为止,我一直希望以相同的方式进行操作。我可能还需要做其他一些事情,例如设置创建日期,上次更新日期等。

到目前为止,我已经考虑过的选项:

  1. 将ID,创建日期等复制粘贴到每个实体中。优点:简便,复制方法可行。缺点:DRY失败,您无法使用共享的超类处理所有实体。(但是可以为此创建一个接口。)

  2. 覆盖超类的值,并将其传递给超类。

您仍然需要将替代值粘贴到每个实体中,但至少不必复制批注。

@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
)
Run Code Online (Sandbox Code Playgroud)
  1. ??? 我什至无法想到第三个可行的选择。还有另一种方法吗?将ID设为var并每次创建自定义复制方法?听起来很丑。

gtc*_*ist 2

我相当确定,由于类型擦除,您将无法使用您定义的类类型来完成此任务。因为你的data classes 正在扩展,abstract class你会遇到很多障碍。

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

fun <T: BaseEntity> T.withBase(base: BaseEntity): T {
    id = base.id
    return this
}
Run Code Online (Sandbox Code Playgroud)

这是一个简单的扩展方法,它位于BaseEntity类定义旁边,您只需将该调用链接到.copy(). 所以你可以按如下方式使用它:

val base = Comment("Created an object")
val copy = base.copy().withBase(base)
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • 这会搞砸你生成的值,因为copy()调用将实例化BaseEntity
  • 您必须记住链接这些调用。

如果您希望在复制时id递增(以及任何值),那么第一个警告就会消失。@AutoGenerated但是,链接仍然是必需的,但是,它确实大大减少了复制/粘贴以及其他可能的错误。