spring-projects / spring-data-r2dbc

Provide support to increase developer productivity in Java when using Reactive Relational Database Connectivity. Uses familiar Spring concepts such as a DatabaseClient for core API usage and lightweight repository style data access.
Apache License 2.0
708 stars 132 forks source link

`bindProperties` throws error when entities contain enum fields #854

Closed detomarco closed 6 months ago

detomarco commented 7 months ago

It seems like entities cannot have enum fields when saving using bindProperties or bind APIs

Spring boot 3.2.2


@Table("cars")
public class Car {
    @Id
    private UUID id;
    private String name;
    private Language language;

   // getters - setters
}

public enum Language {
    EN, NL
}

@Repository
public class CarRepository {

    private final DatabaseClient databaseClient;

    public CarRepository(DatabaseClient databaseClient) {
        this.databaseClient = databaseClient;
    }

    public Car save(Car car) {

        databaseClient.sql("INSERT INTO cars(id,name, language) VALUES(:id,:name, :language)")
                .bindProperties(car)
                .fetch()
                .one()
                .block();

        return car;

    }
}

@Test
void contextLoads() {
    Car car = new Car();
    car.setId(UUID.randomUUID());
    car.setName("BMW");
    car.setLanguage(Language.EN);

    carRepository.save(car);

}

This test throws this exception

java.lang.IllegalArgumentException: Cannot encode parameter of type io.r2dbc.spi.Parameters$InParameter (EN)
    at io.r2dbc.postgresql.codec.DefaultCodecs.encodeParameterValue(DefaultCodecs.java:290)
    at io.r2dbc.postgresql.codec.DefaultCodecs.encode(DefaultCodecs.java:264)
    at io.r2dbc.postgresql.PostgresqlStatement.bind(PostgresqlStatement.java:108)
    at io.r2dbc.postgresql.PostgresqlStatement.bind(PostgresqlStatement.java:59)

Would it be possible to support enumeration in bindProperties api?

Full code here

mp911de commented 6 months ago

Thanks for reaching out. DatabaseClient is part of Spring Framework. It isn't opinionated about enum representations (ordinal vs. name) therefore the value is passed on directly as-is.

I suggest reaching out to Spring Framework and filing a ticket for discussion.

Furthermore, you can use Postgres Enum Types to serialize Java enums to Postgres enums if you wish. However, that requires a bit of driver configuration.