如何在 r2dbc-postgresql 中使用 EnumCodec
how to use EnumCodec in r2dbc-postgresql
我正在尝试使用最新版本的 r2dbc-postgresql (0.8.4) 中的 EnumCodec 失败,我想知道你是否可以帮助我。
我也使用 spring-data-r2dbc 版本 1.1.1.
我从 GitHub 中获取了确切的例子,并在我的 Postgres 中创建了一个枚举类型“my_enum”,
和一个 table “sample_table”,其中包含“名称”(文本)和“值”(my_enum)。
然后我按照例子做了:
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,但表达式的类型为字符变化
你能帮我理解我做错了什么,或者给我一些工作示例吗?
感谢您的帮助!
Spring 默认情况下,数据将枚举值视为要转换为 String
的值。您需要通过按原样编写枚举类型来注册一个保留类型的 Converter
。
@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 数据按预期工作:
- Row.decode(…) fails for enum type with IllegalArgumentException: 72093 is not a valid object id #301
- EnumCodec decoding fails if the requested value type is Object #302
作为临时解决方法,您可以在代码库中复制 EnumCodec
并应用 #302
中的修复程序,直到新版本的 R2DBC Postgres 可用。
我尝试在示例项目中使用 pg 枚举类型和 Java 枚举 class。
如果你正在使用DatabaseClient API(在Spring 5.3核心,不使用Spring Data R2dbc),在PostgresConnectionFactory中注册一个EnumCodec就足够了。
检查my exmaple。
如果在 table 模式中创建一个 pg 类型枚举作为列类型,并在 PostgresConnectionFactory.builder 中注册一个 EnumCodec。您需要编写自定义 @ReadingConverter
才能读取自定义枚举。
如果在 table 架构中使用 text-based type(varchar) 和 Java 枚举。无需额外的转换工作,检查 my example here.
Spring数据R2dbc说如果使用驱动built-in机制来处理枚举,你必须注册一个EnumWriteSupport
。但根据我的经验,当使用Spring Data R2dbc时,写入可以自动处理,但需要读取转换器才能从Postgres读取枚举。
我正在尝试使用最新版本的 r2dbc-postgresql (0.8.4) 中的 EnumCodec 失败,我想知道你是否可以帮助我。
我也使用 spring-data-r2dbc 版本 1.1.1.
我从 GitHub 中获取了确切的例子,并在我的 Postgres 中创建了一个枚举类型“my_enum”, 和一个 table “sample_table”,其中包含“名称”(文本)和“值”(my_enum)。
然后我按照例子做了:
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,但表达式的类型为字符变化
你能帮我理解我做错了什么,或者给我一些工作示例吗? 感谢您的帮助!
Spring 默认情况下,数据将枚举值视为要转换为 String
的值。您需要通过按原样编写枚举类型来注册一个保留类型的 Converter
。
@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 数据按预期工作:
- Row.decode(…) fails for enum type with IllegalArgumentException: 72093 is not a valid object id #301
- EnumCodec decoding fails if the requested value type is Object #302
作为临时解决方法,您可以在代码库中复制 EnumCodec
并应用 #302
中的修复程序,直到新版本的 R2DBC Postgres 可用。
我尝试在示例项目中使用 pg 枚举类型和 Java 枚举 class。
如果你正在使用DatabaseClient API(在Spring 5.3核心,不使用Spring Data R2dbc),在PostgresConnectionFactory中注册一个EnumCodec就足够了。
检查my exmaple。
如果在 table 模式中创建一个 pg 类型枚举作为列类型,并在 PostgresConnectionFactory.builder 中注册一个 EnumCodec。您需要编写自定义
@ReadingConverter
才能读取自定义枚举。如果在 table 架构中使用 text-based type(varchar) 和 Java 枚举。无需额外的转换工作,检查 my example here.
Spring数据R2dbc说如果使用驱动built-in机制来处理枚举,你必须注册一个EnumWriteSupport
。但根据我的经验,当使用Spring Data R2dbc时,写入可以自动处理,但需要读取转换器才能从Postgres读取枚举。