spring-projects / spring-data-relational

Spring Data Relational. Home of Spring Data JDBC and Spring Data R2DBC.
https://spring.io/projects/spring-data-jdbc
Apache License 2.0
771 stars 346 forks source link

spring tries to insert null enums as varchar #1935

Open mattmcc-attest opened 1 week ago

mattmcc-attest commented 1 week ago

Hi, I have an issue with enums using spring-data-jdbc.

I have a Java enum type:

public enum Sentiment {
  POSITIVE,
  NEGATIVE,
  NEUTRAL
}

And a corresponding enum type on one of my tables:

insights=> \dT+ sentiment
                                          List of data types
 Schema |   Name    | Internal name | Size | Elements |    Owner    | Access privileges | Description 
--------+-----------+---------------+------+----------+-------------+-------------------+-------------
 public | sentiment | sentiment     | 4    | POSITIVE+| owner |                   | 
        |           |               |      | NEGATIVE+|             |                   | 
        |           |               |      | NEUTRAL  |             |                   | 
(1 row)

I have this Entity (see the Sentiment field):

@Table("responses")
public record Response(
    @Id UUID id,
    UUID roundId,
    UUID cardTemplateId,
    UUID cardId,
    UUID answerOptionTemplateId,
    UUID answerOptionId,
    String text,
    Sentiment sentiment) {}

If I call save on the repository:

responseRepository.save(new RoundResponse(Id, roundId, UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), "text", null)); // sentiment is null

I get the error:

Caused by: org.postgresql.util.PSQLException: ERROR: column "sentiment" is of type sentiment but expression is of type character varying

I have some Converters for handling the enums but because the value is null it doesn't reach these converters. It seems to me that the spring-data-jdbc library must be at some point trying to convert the null value to a varchar? (maybe by default?)

This is not what I would expect, I would expect if the value I am inserting is null and my enum type postgres field is nullable then null should be used rather than varchar :)

Let me know if you need any more information, thank you!

schauder commented 1 week ago

I think it isn't Spring Data JDBC that tries to convert something here. Instead it seems to tell Postgres, this null value is a VARCHAR` and Postgres is overwhelmed by the task to convert it to an enum ...

mattmcc-attest commented 1 week ago

Yeah I debugged into the JdbcTemplate and could see it was trying to insert with sqlType = 12 = varchar. Not sure at what point spring-data-jdbc is telling Postgres is is a varchar though

mattmcc-attest commented 1 week ago

@schauder Do you think this is a bug? It seems like the MappingJdbcConverter doesn't recognise the type so converts it to a String.

Should there be some function further up the call stack that handles nulls whereby if the value is null then don't try and type it and insert as a null in the DB?

schauder commented 1 week ago

Yes, I do think this is a bug. Could you provide a full reproducer, preferable as github repo?

mattmcc-attest commented 1 week ago

@schauder Thank you :) here is an app that reproduces it https://github.com/mattmcc-attest/animal