【发布时间】:2023-03-30 22:30:01
【问题描述】:
我正在从传统的 JPA 代码库迁移并面临一个问题,即无法通过将 id 设置为零来保存新实体。
这是我的架构 (PostreSQL):
CREATE TABLE my_user (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
在 JPA 中,我可以将 id 设置为0,它将被视为一个新实体。将自动分配一个新的 ID。
但是在 R2DBC 中,新实体总是以 id = 0 保存,这是不可能的。
我知道,我可以为此使用 Integer 或 Long 并将它们设置为 null,但我正在使用 Kotlin 并希望使 id 不可为空。否则我必须做大量不必要的空检查。
userRepo.save(User(0, "A New User")) // works
userRepo.save(User(0, "Another New User")) // error, same id (but works in JPA)
@Table("my_user")
data class User(@Id var id: Int = 0,
var name: String = "")
【问题讨论】:
-
为什么
0会被 JPA 视为一个新实体?为什么需要对主键进行空检查?您根本不应该在代码中触及它。 -
@Kayaman 因为我必须在我的 Kotlin 代码中声明 id 可为空,例如
@Id var id: Int?。每次我访问 id 时,Kotlin 编译器都会强制我检查它是否为空。在 JPA 中,如果 id 是原始的,则将零视为新的 -
但是你为什么要访问
id?它是一个数据库主键。您的应用程序知道它对于新实体是 null 而对于现有实体是非 null,但它不应该分配或访问它。 -
因为我正在处理外键。例如
postRepo.save(Post(0, user.id, "Some Text"))。我正在访问user.id -
似乎是因为JPA and Spring Data之间的处理方式不同。
标签: java spring kotlin spring-data-r2dbc r2dbc