3

我正在尝试使用最新版本的 r2dbc-postgresql (0.8.4) 中的 EnumCodec 失败,我想知道您是否可以帮助我。

我也使用 spring-data-r2dbc 1.1.1 版。

我从 GitHub 中获取了确切的示例,并在我的 Postgres 中创建了一个枚举类型“my_enum”,以及一个包含“name”(文本)和“value”(my_enum)的表“sample_table”。

然后我按照示例进行操作:

SQL:

CREATE TYPE my_enum AS ENUM ('FIRST', 'SECOND');

Java模型:

enum MyEnumType {
  FIRST, SECOND;
}

编解码器注册:

PostgresqlConnectionConfiguration.builder()
.codecRegistrar(EnumCodec.builder().withEnum("my_enum", MyEnumType.class).build());

我使用 DatabaseClient 来与数据库通信。我尝试使用 2 种方法插入:

databaseClient.insert().into(SampleTable.class)
.using(sampleTable).fetch().rowsUpdated();

或者:

databaseClient.insert().into("sample_table")
.value("name", sampleTable.getName())
.value("value", sampleTable.getValue())
.then();

其中 SampleTable 是:

@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;
}

但是我同时使用这两种方法得到了同样的错误:

列“值”的类型为 my_enum,但表达式的类型为字符变化

你能帮我理解我做错了什么,或者让我参考一些工作示例吗?我感谢您的帮助!

4

2 回答 2

3

Spring Data 将枚举值视为默认转换为String的值。您需要Converter通过按原样编写枚举类型来注册保留类型的 a。

@WritingConverter
class MyEnumTypeConverter implements Converter<MyEnumType, MyEnumType> {
    @Override
    public MyEnumType convert(MyEnumType source) {
        return source;
    }
}

接下来,您需要注册转换器。如果您使用的是 Spring Data R2DBC AbstractR2dbcConfiguration,则覆盖getCustomConverters()

class MyConfiguration extends AbstractR2dbcConfiguration {

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

  // …
}

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

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 驱动程序中有两个错误会阻止 Spring Data 按预期工作:

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

于 2020-07-22T13:22:35.500 回答
0

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

  1. 如果您使用 DatabaseClient API(在 Spring 5.3 核心中,不使用 Spring Data R2dbc),在 PostgresConnectionFactory 中注册一个 EnumCodec 就足够了。

    检查我的例子

  2. 如果在表模式中创建一个 pg 类型枚举作为列类型,并在 PostgresConnectionFactory.builder 中注册一个 EnumCodec。您需要编写自定义@ReadingConverter来读取自定义枚举。

    在这里查看我的示例

  3. 如果在 Java Enum 的表模式中使用基于文本的类型 ( varchar )。无需额外的转换工作,请在此处查看我的示例

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

于 2020-09-13T12:51:41.173 回答