首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在r2dbc-postgresql中使用EnumCodec

如何在r2dbc-postgresql中使用EnumCodec
EN

Stack Overflow用户
提问于 2020-07-22 10:14:21
回答 2查看 3.7K关注 0票数 5

我正在尝试使用来自r2dbc-postgresql (0.8.4)的最新版本的EnumCodec,但没有成功,我想知道您是否可以帮助我。

我还使用了spring r2dbc版本1.1.1。

我以GitHub为例,在Postgres中创建了一个枚举类型“my_enum”,以及一个包含‘name’(文本)和‘value’(my_enum)的表“sample_table”。

然后,我做了一个例子:

SQL:

代码语言:javascript
复制
CREATE TYPE my_enum AS ENUM ('FIRST', 'SECOND');

Java模型:

代码语言:javascript
复制
enum MyEnumType {
  FIRST, SECOND;
}

编解码器注册:

代码语言:javascript
复制
PostgresqlConnectionConfiguration.builder()
.codecRegistrar(EnumCodec.builder().withEnum("my_enum", MyEnumType.class).build());

我使用DatabaseClient来与DB通信。我尝试使用两种方法插入:

代码语言:javascript
复制
databaseClient.insert().into(SampleTable.class)
.using(sampleTable).fetch().rowsUpdated();

或者:

代码语言:javascript
复制
databaseClient.insert().into("sample_table")
.value("name", sampleTable.getName())
.value("value", sampleTable.getValue())
.then();

其中SampleTable是:

代码语言:javascript
复制
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table("sample_table")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SampleTable implements Serializable {
   private String name;
   @Column("value")
   @JsonProperty("value")
   private MyEnumType value;
}

但我使用这两种方法得到相同的错误:

列"value“的类型为my_enum,而表达式的类型为变量

你能不能帮我理解一下我做错了什么,或者给我举个例子?我很感激你的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-22 13:22:35

Spring数据将枚举值视为默认转换为String的值。您需要注册一个保留类型的Converter,方法是按原样写入枚举类型。

代码语言:javascript
复制
@WritingConverter
class MyEnumTypeConverter implements Converter<MyEnumType, MyEnumType> {
    @Override
    public MyEnumType convert(MyEnumType source) {
        return source;
    }
}

接下来,您需要注册转换器。如果使用SpringDataR2DBC的AbstractR2dbcConfiguration,则重写getCustomConverters()

代码语言:javascript
复制
class MyConfiguration extends AbstractR2dbcConfiguration {

    @Override
    protected List<Object> getCustomConverters() {
        return Collections.singletonList(new MyEnumTypeConverter());
    }

  // …
}

或者,如果您配置DatabaseClient独立,那么您需要更多的代码:

代码语言:javascript
复制
PostgresqlConnectionConfiguration configuration = PostgresqlConnectionConfiguration.builder()
        .codecRegistrar(EnumCodec.builder().withEnum("my_enum", MyEnumType.class).build())
        .host(…)
        .username(…)
        .password(…)
        .database(…).build();

R2dbcDialect dialect = PostgresDialect.INSTANCE;
DefaultReactiveDataAccessStrategy strategy = new DefaultReactiveDataAccessStrategy(dialect, Collections.singletonList(new MyEnumTypeConverter()));

DatabaseClient databaseClient = DatabaseClient.builder()
        .connectionFactory(new PostgresqlConnectionFactory(configuration))
        .dataAccessStrategy(strategy)
        .build();

但是,R2DBC驱动程序中有两个bug阻止Spring数据按预期工作:

作为临时解决办法,您可以在代码库中复制EnumCodec,并从#302中应用修复程序,直到R2DBC Postgres的新版本可用为止。

票数 5
EN

Stack Overflow用户

发布于 2020-09-13 12:51:41

我尝试在我的示例项目中使用pg枚举类型和Java类。

  1. 如果您使用的是DatabaseClient API(在Spring5.3内核中,而不是使用Spring R2dbc),那么在PostgresConnectionFactory中注册一个EnumCodec就足够了。 检查我的前妻
  2. 如果将pg类型枚举创建为表架构中的列类型,并在EnumCodec中注册一个PostgresConnectionFactory.builder。您需要编写自定义@ReadingConverter来读取自定义枚举。 检查我在这里的例子
  3. 如果您在带有Java的表模式中使用基于文本的type(varchar)。不需要在转换上付出额外的努力,检查我在这里的例子

Spring R2dbc说,如果使用驱动程序内置机制来处理enum,就必须注册一个EnumWriteSupport。但是根据我的经验,当使用Spring R2dbc时,可以自动处理写入,但是从Postgres读取枚举需要读取转换器。

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

https://stackoverflow.com/questions/63031908

复制
相关文章

相似问题

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