如何修复数据转换错误:jdbcTemplate.update,将 Enum 写入 H2 数据库

Posted

技术标签:

【中文标题】如何修复数据转换错误:jdbcTemplate.update,将 Enum 写入 H2 数据库【英文标题】:How to fix data conversion error: jdbcTemplate.update, writing Enum to H2 database 【发布时间】:2021-06-30 08:55:05 【问题描述】:

我将 PostgreSql 用于我的主要代码并使用 H2 进行测试,并得到不同的结果(测试失败)。 我的类有一个枚举类型字段

public class Student 
    private int id;
    private String firstName;
    private String lastName;
    private Gender gender;

public enum Gender 
    MALE, FEMALE;

SQL 架构是

CREATE TABLE students (
id integer NOT NULL generated BY DEFAULT AS identity,
first_name VARCHAR(255),
last_name VARCHAR(255),
gender GENDER
);
CREATE TYPE gender AS ENUM ('MALE','FEMALE');

我的 DAO 课程

public class JdbcStudentDao 
    private static final String CREATE = "INSERT INTO students (first_name, last_name, gender) VALUES (?, ?, ?)";

    KeyHolder keyHolder = new GeneratedKeyHolder();
    public void create(Student student) 
    jdbcTemplate.update(connection -> 
        PreparedStatement ps = connection
            .prepareStatement(CREATE, Statement.RETURN_GENERATED_KEYS);
        ps.setString(1, student.getFirstName());
        ps.setString(2, student.getLastName());
        ps.setObject(3, student.getGender(), java.sql.Types.OTHER);
        return ps;
    , keyHolder);
    student.setId((int) keyHolder.getKeys().get("id"));
    

在我的测试方法中:

Student student = new Student("Name", "Lastname", Gender.MALE);
jdbcStudentDao.create(student);

一切都适用于 PostgreSql,但使用 H2 测试失败并出现数据转换错误:

org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; (STUDENTS: ""GENDER"" ""GENDER"")"
Data conversion error converting (STUDENTS: ""GENDER"" ""GENDER"")"; SQL statement:
INSERT INTO students (first_name, last_name, gender) VALUES (?, ?, ?) 

我认为我在 PreparedStatement for Gender 中使用的“java.sql.Types.OTHER”是由 Postgres 自动转换的,而不是由 H2 引擎转换的。 http://www.h2database.com/html/datatypes.html#enum_type 表示 Enum 映射到 Integer。这是问题吗?有解决办法吗?

【问题讨论】:

【参考方案1】:

H2 数据库引擎不支持 Enum 值,因为它是在 Postgre 中实现的。 我使用解决方法解决了我的问题:

    从 SQL 架构中删除了 Enum 类型声明 用 Varchar 类型替换 SQL 模式中的 Enum 字段(但不是在 Java 模型类中) 在更新和创建方法中使用 .toString() 修改了 Dao 层

现在测试在两个数据库中都能正常运行。

public class JdbcStudentDao 
    private static final String CREATE = "INSERT INTO students (first_name, last_name, gender) VALUES (?, ?, ?)";

    KeyHolder keyHolder = new GeneratedKeyHolder();
    public void create(Student student) 
    jdbcTemplate.update(connection -> 
        PreparedStatement ps = connection
            .prepareStatement(CREATE, Statement.RETURN_GENERATED_KEYS);
        ps.setString(1, student.getFirstName());
        ps.setString(2, student.getLastName());
        ps.setString(3, student.getGender().toString());
        return ps;
    , keyHolder);
    student.setId((int) keyHolder.getKeys().get("id"));
    

【讨论】:

以上是关于如何修复数据转换错误:jdbcTemplate.update,将 Enum 写入 H2 数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何修复“错误转换列:0 TO TIMESTAMP”?

如何使用 DbContext 和 SetInitializer 修复 datetime2 超出范围的转换错误?

如何使用带有可分页的 mongorepository 修复转换错误

将列表转换为 csv 格式时如何修复编码错误?

如何修复 profanity_filter 字符串转换错误

从java转换后如何修复typescript类文件错误?