我从个人经验和this discussion 都了解当 data class
从另一个类继承时,该继承类的字段不包含在数据类的 copy
函数中。
我对解决此问题的选项很感兴趣。
具体来说,我有一个 JPA @MappedSuperClass
用于我的 JPA 实体,它们是 data class
es。在父类(super class)中,我设置了实体 ID,(至少到目前为止)我总是想这样做。我可能还想做一些其他的事情,比如设置创建日期、上次更新日期等。
到目前为止我考虑过的选项:
将 ID、创建日期等复制粘贴到每个实体中。优点:它很简单,并且复制方法有效。缺点: DRY 失败,您无法使用共享父类(super class)处理所有实体。 (但可以为此创建一个界面。)
覆盖父类(super class)的值并将它们传递给父类(super class)。
您仍然需要将覆盖值复制粘贴到每个实体中,但至少您不必复制注释。
@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
)
- ???我什至想不出第三个可行的选择。还有另一种方法吗?将 ID 设为 var 并每次都创建自定义复制方法?听起来很难看。
最佳答案
我相当肯定,由于类型删除,您将无法使用您定义的类类型来完成此操作。因为你的 data class
es 正在扩展一个 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
值),那么第一个警告就会消失。但是,仍然需要链接,但是它确实大大减少了复制/粘贴和其他可能的错误。
关于jpa - Kotlin数据类继承+拷贝方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47320136/