How to fix data conversion error: jdbcTemplate.update, writing Enum to H2 database

How to fix data conversion error: jdbcTemplate.update, writing Enum to H2 database

我使用 PostgreSql 作为我的主要代码,使用 H2 进行测试,但得到了不同的结果(测试失败)。 我的 class 具有枚举类型字段

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 class

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。这是问题吗?有解决方法吗?

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

  1. 从 SQL 架构中删除了枚举类型声明
  2. 用 Varchar 类型替换了 SQL 模式中的枚举字段(但不在 Java 模型 class 中)
  3. 在更新和创建方法中使用 .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"));
    }
}