首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring数据R2DBC PostgreSQL没有用UUID @Id保存新记录

Spring数据R2DBC PostgreSQL没有用UUID @Id保存新记录
EN

Stack Overflow用户
提问于 2022-01-27 11:36:42
回答 5查看 2.7K关注 0票数 4

我有一个简单的实体,由两个UUID组成:

代码语言:javascript
复制
@Table("library")
public class LibraryDao {
    @Id
    private UUID id;
    @NonNull
    private UUID ownerId;
}

我在PostgreSQL中有一个相应的表:

代码语言:javascript
复制
CREATE TABLE IF NOT EXISTS library (id UUID PRIMARY KEY, owner_id UUID NOT NULL);

我正在使用正确的R2DBC驱动程序(io.r2dbc:r2dbc-postgresqlorg.postgresql:postgresql)。

到目前为止,一切都正常。我的掌声响起了。但是…

因为PostgreSQL (至少根据文档)没有UUID的自动生成函数,所以我在创建新的LibraryDao实例时设置了id。

然而,当我在我的存储库中调用save方法时,我得到了一个异常:Failed to update table [library]. Row with Id [0ed4d7c0-871a-4473-8997-4c9c1ec67a00] does not exist.

save似乎被解释为update,如果它不存在的话,它将不会倒退到insert

我应该如何在数据库中插入新的记录?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2022-01-27 15:17:39

尽管有PostgreSQL文档,仍然有一种使用pgcrypto扩展(用于v4 UUID)自动生成UUID的方法。(基于使用pgAdmin GUI的过程。)

在查询工具中:

  • select * from pg_extension并检查pgcrypto没有列出。
  • create extension pgcrypto来安装它;它附带默认安装。

然后,将列定义改为... id UUID PRIMARY KEY DEFAULT gen_random_uuid(), ...

而且它是有效的。

票数 2
EN

Stack Overflow用户

发布于 2022-02-03 13:49:01

因为R2DBC还没有自动生成UUID,而在Spring中使用的工具有自己的机制来防止向DB发送空(因此不能使用触发器来完成这项工作)--也许这里的最佳解决方案是使用UUID.randomUUID();生成UUID,并在将实体发送到DB之前将它们放在实体中。

编辑-具体解决方案:

解决方案的一个小问题是,必须对DB安装进行修改。

在实现了所描述的插入问题之后,我不再尝试使用存储库save方法,而是使用R2DBC DatabaseClient切换到“手动”解决方案。

代码语言:javascript
复制
dbClient.sql("insert into product_price(id, product_id, price) values(:id, :product_id, :price)")
      .bind("id", UUID.randomUUID())
      .bind("product_id", 1)
      .bind("price", 10.0)
      .fetch()
      .one()
      .subscribe();

下面是DatabaseClient,它是从ConnectionFactory配置的,启用后可以接受命名参数:

代码语言:javascript
复制
@Bean
public DatabaseClient dbClient(ConnectionFactory connectionFactory) {
    return DatabaseClient.builder()
            .connectionFactory(connectionFactory)
            .namedParameters(true)
            .build();
}

ConnectionFactory也是我在扩展AbstractR2dbcConfiguration的配置类中公开的易于定制的Bean。

并且希望,反应性存储库中的save()将得到改进,以与其他春季数据存储库中的对应程序相媲美。

票数 0
EN

Stack Overflow用户

发布于 2022-02-04 22:40:52

但是,除了我关于使用R2DBC DatabaseClient执行插入的R2DBC之外,还有一种使用反应性存储库的save方法来实现它的方法--通过使用可持续接口,这是非常直接的。

它的isNew方法可以使用实体的version attribut来实现,或者通过添加一个新的专用attribut (类似于boolean isAlreadyPersisted)来实现,可以在调用save()之前显式地设置它。也许还有其他一些我不知道的使用Persistable的方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70877916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档