如何使用 Kotlin 在 Spring Boot 中扩展实体类



经过几年的Python开发,试图学习Spring Boot和Kotlin。

并且不知道如何使用created_atupdated_at列扩展Entity

我将尝试使用python来表示我正在寻找的内容:

@dataclass
class TableWithTime:
created_at: datetime
updated_at: datetime
@dataclass
class TableWithDefaultId:
id: int
@dataclass
class User(TableWithDefaultId, TableWithTime):
name: str

这里有TableWithDefaultIdTableWithTime可以称为MixIns

当我们创建User实例时:

u = User(
id = 1,
name = "John",
created_at = datetime.datetime.now(),
updated_at = datetime.datetime.now()
)

所有属性都将包括在内,例如,我们将能够调用u.created_at

现在我尝试用 Kotlin 和 Spring Boot 实现同样的事情:

@Entity
abstract class TableWithTime(
@CreatedDate
@Column(nullable = false, updatable = false)
var created_at: Date,
@LastModifiedDate
@Column(nullable = false)
var updated_at: LocalDateTime
)
@Entity
abstract class TableWithStandardId(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0
)
@Entity
data class User(
var name: String
): TableWithTime(), TableWithStandardId()

第一个问题是 IDE 告诉我:

没有为参数"created_at"传递值
没有为参数"updated_at"传递任何值

对于TableWithTime()类。但我不想实例化TableWithTime类并立即设置参数

第二个问题是

超类型列表中只能显示一个类

而且不可能像我在 Python 中那样用两个超级类来扩展User类。

所以问题是,实现公共IDcreated_at/updated_at列而不手动将其作为参数添加到每个Entity类的更近和最好的解决方案是什么?

您正在寻找@MappedSuperclass注释。

这个注解几乎告诉JPA/Spring它具有其他@Entity类的共享属性。在那些@MappedSupperclass里,你像往常一样工作,让春天发挥它的魔力。

@MappedSuperclass
abstract class TableWithTime(
@CreatedDate
@Column(nullable = false, updatable = false)
var created_at: Date,
@LastModifiedDate
@Column(nullable = false)
var updated_at: LocalDateTime
)
@MappedSuperclass
abstract class TableWithStandardId(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0
)
@Entity
data class User(
var name: String
): TableWithTime(), TableWithStandardId() // this is wrong, see updated answer

(我不熟悉 Kotlin,我建议你仔细检查语法。

更新

首先,我很抱歉,因为我缺乏对 Kotlin 的了解导致我误读了代码。现在检查一下语言,我看到了我的错误,但我会保留答案,希望它可以让你朝着正确的方向前进。那么,下面的代码是我们如何在 Java 中的 Spring/JPA 中处理@MappedSuperclass的插值,以及我到目前为止读到的 Kotlin 内容。由于这可能不是有效的 Kotlin,请将其视为伪代码。

如果需要这两个抽象类,则需要第三个抽象类,或者使用接口。由于大多数表可能使用 ID,因此我会为TableWithStandardId声明一个接口,以便更好地控制@GeneratedValue注释。

@MappedSuperclass
abstract class TableWithTime {
@CreatedDate
@Column(nullable = false, updatable = false)
var created_at: Date,
@LastModifiedDate
@Column(nullable = false)
var updated_at: LocalDateTime
}
interface TableWithStandardId {
var id: Long
}
@Entity
class User (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
override var id: Long = 0,
var name: String
): TableWithTime(), TableWithStandardId

请注意,我没有在构造函数中"声明"抽象类的属性,而是在类主体中"声明"抽象类的属性。

最新更新