Hibernate 6+ 无法映射Java枚举到PostgreSQL枚举问题求助
Hibernate 6 升级后PostgreSQL枚举类型存储问题
升级到Hibernate 6后,原来用来处理PostgreSQL枚举的@TypeDef注解被移除,保存枚举时出现类型不匹配错误。
当前实体类代码:
@Enumerated(value = EnumType.STRING) @Type(MyPSQLType.class) private MyType myType;
自定义的PostgreSQL类型处理类:
public class MyPSQLType extends org.hibernate.type.EnumType<MyType> { @Override public void nullSafeSet(PreparedStatement st, MyType value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { st.setObject(index, value != null ? value.name() : null, Types.OTHER); } }
报错信息:
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: my_type = character varying Hint: No operator matches the given name and argument types. You might need to add explicit type casts. Position: 187
疑问:@TypeDef用不了了,是不是得换别的方式注册自定义类型?
解决方案
1. 用Hibernate 6原生映射,去掉冗余代码
Hibernate 6对PostgreSQL枚举的支持已经做了优化,不需要再自定义EnumType子类,也不用加@Type注解。直接这么写就行:
@Enumerated(EnumType.STRING) @Column(columnDefinition = "my_type") private MyType myType;
注意:数据库里的枚举类型名称(比如my_type)要和Java枚举的name()值完全匹配,大小写敏感。
2. 复杂场景下注册自定义类型
如果一定要保留自定义类型的逻辑,Hibernate 6用@TypeRegistration代替原来的@TypeDef:
- 在自定义类型类上加注解,关联对应的SQL类型:
@TypeRegistration(sqlTypes = SqlTypes.OTHER, defaultForType = MyType.class) public class MyPSQLType extends org.hibernate.type.EnumType<MyType> { @Override public void nullSafeSet(PreparedStatement st, MyType value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { st.setObject(index, value != null ? value.name() : null, Types.OTHER); } }
- 实体类里只保留
@Enumerated注解就行:
@Enumerated(EnumType.STRING) private MyType myType;
3. 核对数据库与Java枚举的一致性
确保数据库创建的枚举类型值和Java枚举完全对应,比如PostgreSQL里创建枚举的SQL:
CREATE TYPE my_type AS ENUM ('VALUE1', 'VALUE2', 'VALUE3');
对应的Java枚举:
public enum MyType { VALUE1, VALUE2, VALUE3; }
内容的提问来源于stack exchange,提问作者planktonchumbucket
相关产品推荐
相关产品推荐

