我有一个简单的实体,由两个UUID组成:
@Table("library")
public class LibraryDao {
@Id
private UUID id;
@NonNull
private UUID ownerId;
}
我在PostgreSQL中有一个对应的表:
CREATE TABLE IF NOT EXISTS library (id UUID PRIMARY KEY, owner_id UUID NOT NULL);
我正在使用正确的R2DBC驱动程序(io.r2dbc:r2dbc-postgresql
和org.postgresql:postgresql
)。
在这一点上,一切正常。我的应用程序运行。但是...
因为PostgreSQL没有(至少根据文档)UUID的自动生成功能,所以我在创建新的LibraryDao
示例时设置id。
但是,当我在Repository中调用save
方法时,我得到一个异常:Failed to update table [library]. Row with Id [0ed4d7c0-871a-4473-8997-4c9c1ec67a00] does not exist.
看起来save
被解释为update
,如果不存在,则没有回退到insert
。
我该如何在数据库中插入新记录?
6条答案
按热度按时间vhipe2zx1#
除了PostgreSQL文档,还有一种方法可以使用pgcrypto扩展(用于v4 UUID)自动生成UUID。(基于使用pgAdmin GUI的过程。)
在查询工具中:
select * from pg_extension
并检查pgcrypto是否未列出。create extension pgcrypto
安装它;它是默认安装的。然后,使用将列定义更改为
... id UUID PRIMARY KEY DEFAULT gen_random_uuid(), ...
而且很管用。
bvjxkvbb2#
然而,除了我的answer关于使用R2 DBC
DatabaseClient
进行插入之外,还有一种方法可以使用React式存储库的save
方法-通过使用Persistable接口,这是非常直接的。它的
isNew
方法可以使用实体的version
属性来实现,或者通过添加一个新的专用属性(类似于boolean isAlreadyPersisted
)来实现,该属性可以在调用save()
之前显式设置。628mspwn3#
由于R2 DBC还没有自动生成UUID,并且Spring内部使用的工具有自己的机制,可以防止向DB发送null(因此无法使用触发器来完成这项工作)-也许这里的最佳解决方案是使用Java(
UUID.randomUUID();
)生成UUID,并在将实体发送到DB之前将其放入实体中。编辑-具体解决方案:
您的解决方案的一个小问题是必须修改DB安装。
在意识到上述插入问题后,我放弃了使用存储库
save
方法来执行此操作,并切换到使用R2 DBCDatabaseClient
的“手动”解决方案:下面是
DatabaseClient
,它是从ConnectionFactory
配置的,并允许接受命名参数:ConnectionFactory
也是我在扩展AbstractR2dbcConfiguration
的配置类中公开的一个易于定制的Bean。希望reactive repository中的
save()
能够得到改进,使其表现得像其他spring-data repository中的对应物一样。h22fl7wq4#
因为您已经提供了
@Id
。库需要确定该行是新的还是应该存在。Mark Paluch已经在spring-data-r2 dbc issues board上回答了这个问题。请参阅#275以获取更多参考。此外,您还可以从#49中找到有用的信息。
nimxete25#
我已经阅读和研究了上面的内容,不仅在这里,但是,它并没有解决问题。这是不够的。
您的字段(主键)必须有一个列类型,例如serial,这样数据库在插入记录时,会自动增加记录id。
没有这个,所有其他食谱将无法工作。
pxy2qtax6#
UUID可以自动生成,如果您自己生成它,Hibernate会看到具有id的实体并尝试更新它。
要自动生成uuid,只需在字段上使用以下注解:
来源:https://thorben-janssen.com/generate-uuids-primary-keys-hibernate/