如果主密钥不是零,则弹簧数据JPA不允许实体持久



我有一个订户实体,该实体使用用户提供的电子邮件地址作为主键,而不是自动生成的值。这意味着,当调用JParepository的保存方法时,主要键值为不是null

弹簧数据JPA文档第2.2.1节表2.2 说以下内容:

默认情况下,弹簧数据JPA检查给定的ID-roperty 实体。如果ID-Property为null,则将假定该实体为 新的,否则不是新的。

这种行为阻止了新的订户实体被持续到数据库。

在决定如何选择实体的主键时,我们有两个选项。 1.使用Spring提供的自动生成密钥 2.使用自定义主键,例如电子邮件地址。

自动生成的键更容易使用。当坚持实体时,Spring会注意到ID字段是空的,并得出结论,这个新实体被持续存在。将新的自动生成值分配给ID字段,并将实体持续存在。但是,如果要确保没有持续使用相同电子邮件地址的两个实体,请记住用@Column(unique="true")注释电子邮件字段。由于对电子邮件字段的唯一约束,检测重复项也很容易。

但是,有时您不想使用自动生成的密钥,因为您可能想将提供的电子邮件地址用作密钥。这种方法没有问题。用@ID在实体中标记电子邮件字段。就这样。但是,不可能进行重复检测。如果多次收到具有相同电子邮件地址的实体的请求,则每次都会更新相同的实体,即每次都会进行EntityManager.merge()。违反约束的例外将不会提出。回想一下,Spring总是检查主要密钥字段是否为空字段,以决定是创建新实体还是合并到现有实体中。

同一张表告诉您如何自定义该行为。

让您的实体实现Persistable和覆盖isNew,或提供EntityInformation的自定义实现。

最新更新