Spring Boot 3迁移:@Type(ClassType)代码适配问题咨询
Spring Boot 3 迁移:Hibernate Class类型映射问题
问题背景
原Spring Boot 2及更早版本代码:
@Column(name = "OPTION_TYPE") @Type(type = "org.hibernate.type.ClassType") private Class<T> clazz;
迁移到Spring Boot 3后报错:
Cannot resolve method 'type'
尝试替换为以下代码后出现新错误:
@Column(name = "OPTION_TYPE") @JdbcTypeCode(SqlTypes.JAVA_OBJECT) private Class<T> clazz;
错误日志:
Caused by: jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Unable to determine SQL type name for column 'option_type' of table 'account_options' because there is no type mapping for org.hibernate.type.SqlTypes code: 2000 (JAVA_OBJECT) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-6.1.5.jar!/:6.1.5] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.1.5.jar!/:6.1.5] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366) ~[spring-orm-6.1.5.jar!/:6.1.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1833) ~[spring-beans-6.1.5.jar!/:6.1.5] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-6.1.5.jar!/:6.1.5] ... 92 common frames omitted Caused by: org.hibernate.MappingException: Unable to determine SQL type name for column 'option_type' of table 'account_options' because there is no type mapping for org.hibernate.type.SqlTypes code: 2000 (JAVA_OBJECT)
解决方案
方法1:使用Hibernate 6.x原生类型(推荐)
Spring Boot 3搭配的Hibernate 6.x重构了类型系统,原ClassType替换为ClassJavaType,需明确指定数据库列类型:
import jakarta.persistence.Column; import org.hibernate.annotations.Type; import org.hibernate.type.descriptor.java.ClassJavaType; @Column(name = "OPTION_TYPE", columnDefinition = "VARCHAR(255)") @Type(ClassJavaType.class) private Class<T> clazz;
方法2:自定义类型处理类
若方法1不生效,可自定义类型处理类实现类型转换:
import org.hibernate.type.AbstractSingleColumnStandardBasicType; import org.hibernate.type.descriptor.java.ClassJavaType; import org.hibernate.type.descriptor.jdbc.VarcharJdbcType; public class ClassType extends AbstractSingleColumnStandardBasicType<Class<?>> { public static final ClassType INSTANCE = new ClassType(); public ClassType() { super(VarcharJdbcType.INSTANCE, ClassJavaType.INSTANCE); } @Override public String getName() { return "class"; } }
实体类中使用:
@Column(name = "OPTION_TYPE", columnDefinition = "VARCHAR(255)") @Type(ClassType.class) private Class<T> clazz;
方法3:手动处理类名存储
放弃ORM自动转换,直接存储类全限定名字符串,手动实现类型转换:
@Column(name = "OPTION_TYPE", length = 255) private String className; // 手动转换方法 public Class<T> getClazz() throws ClassNotFoundException { return (Class<T>) Class.forName(className); } public void setClazz(Class<T> clazz) { this.className = clazz.getName(); }
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

