如何修复数据转换错误: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 数据库的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 DbContext 和 SetInitializer 修复 datetime2 超出范围的转换错误?