Estoy tratando de usar EnumCodec de la última versión de r2dbc-postgresql (0.8.4) sin éxito, y me preguntaba si podría ayudarme.
También uso spring-data-r2dbc versión 1.1.1.
Tomé el ejemplo exacto de GitHub y creé un tipo de enumeración "my_enum" en mi Postgres, y una tabla "sample_table" que contiene 'nombre' (texto) y 'valor' (my_enum).
Luego hice como en el ejemplo:
SQL:
CREATE TYPE my_enum AS ENUM ('FIRST', 'SECOND');Modelo Java:
enum MyEnumType { FIRST, SECOND; }Registro de códec:
PostgresqlConnectionConfiguration.builder() .codecRegistrar(EnumCodec.builder().withEnum("my_enum", MyEnumType.class).build());Uso DatabaseClient para comunicarme con la base de datos. Traté de insertar usando 2 métodos:
databaseClient.insert().into(SampleTable.class) .using(sampleTable).fetch().rowsUpdated();o:
databaseClient.insert().into("sample_table") .value("name", sampleTable.getName()) .value("value", sampleTable.getValue()) .then();donde TablaMuestra es:
@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; }Pero me sale el mismo error usando ambos:
la columna "valor" es de tipo my_enum pero la expresión es de tipo carácter variable
¿Puede por favor ayudarme a entender lo que hice mal, o referirme a algún ejemplo de trabajo? ¡Aprecio tu ayuda!
Spring Data considera los valores de enumeración como valores que se convertirán a String de forma predeterminada. Debe registrar un Converter que conserve el tipo escribiendo el tipo de enumeración tal como está.
@WritingConverter class MyEnumTypeConverter implements Converter<MyEnumType, MyEnumType> { @Override public MyEnumType convert(MyEnumType source) { return source; } } A continuación, debe registrar el convertidor. Si está utilizando AbstractR2dbcConfiguration de Spring Data R2DBC, anule getCustomConverters() :
class MyConfiguration extends AbstractR2dbcConfiguration { @Override protected List<Object> getCustomConverters() { return Collections.singletonList(new MyEnumTypeConverter()); } // … } Alternativamente, si configura DatabaseClient independiente, entonces necesita un poco más de código:
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();Sin embargo, hay dos errores en el controlador R2DBC que impiden que Spring Data funcione como se esperaba:
Como solución temporal, puede duplicar EnumCodec en su base de código y aplicar la corrección del #302 hasta que esté disponible una nueva versión de R2DBC Postgres.
He intentado usar el tipo pg enum y la clase Java Enum en mis proyectos de muestra.
Si está utilizando la API de DatabaseClient (en Spring 5.3 core, no use Spring Data R2dbc), registrar un EnumCodec en PostgresConnectionFactory es suficiente.
Mira mi ejemplo .
Si crea una enumeración de tipo pg como un tipo de columna en el esquema de la tabla, y registre un EnumCodec en PostgresConnectionFactory.builder. Debe escribir @ReadingConverter personalizado para leer la enumeración personalizada.
Mira mi ejemplo aquí .
Si usa un tipo basado en texto ( varchar ) en el esquema de la tabla con Java Enum. no es necesario un esfuerzo adicional en la conversión, consulte mi ejemplo aquí .
Spring Data R2dbc dijo que si usa el mecanismo integrado del controlador para manejar la enumeración, debe registrar un EnumWriteSupport . Pero según mi experiencia, cuando se usa Spring Data R2dbc, la escritura se puede manejar automáticamente, pero se requiere un convertidor de lectura para leer la enumeración de Postgres.