Spring Boot 2.7.3集成Spring Data JPA遇charset类找不到异常求助
在Spring Boot 2.7.3 Web应用中集成Spring Data JPA(通过org.springframework.boot:spring-boot-starter-data-jpa引入),当前使用Hibernate 5.6.9,启动时抛出ClassNotFoundException: Could not load requested class : charset,错误栈如下:
Caused by: java.lang.ClassNotFoundException: Could not load requested class : charset at org.hibernate.boot.registry.classloading.internal.AggregatedClassLoader.findClass(AggregatedClassLoader.java:210) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at java.lang.ClassLoader.loadClass(ClassLoader.java:587) ~[?:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?] at java.lang.Class.forName0(Native Method) ~[?:?] at java.lang.Class.forName(Class.java:467) ~[?:?] at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:130) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.hibernate.boot.internal.ClassLoaderAccessImpl.classForName(ClassLoaderAccessImpl.java:67) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:536) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.hibernate.cfg.SetSimpleValueTypeSecondPass.doSecondPass(SetSimpleValueTypeSecondPass.java:25) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1653) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1621) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:295) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.22.jar:5.3.22] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.22.jar:5.3.22] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.22.jar:5.3.22] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.22.jar:5.3.22] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.22.jar:5.3.22]
当前Spring Data JPA配置类如下:
@Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = "com.bottomline.dm.core.repository.roc", entityManagerFactoryRef = "rocJpaEntityManagerFactory", transactionManagerRef = "rocJpaTransactionManager" ) public class RocJpaDatabaseConfig { private final DataSource rocDataSource; public RocJpaDatabaseConfig(ROCDataSourceProperties rocDataSourceProperties) { this.rocDataSource = rocDataSourceProperties.getPostgresHikariDataSource(); DataSourceInfoLogger infoLogger = new DataSourceInfoLogger(rocDataSource); infoLogger.afterPropertiesSet(); } @Bean public LocalContainerEntityManagerFactoryBean rocJpaEntityManagerFactory() { LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); factory.setPackagesToScan("com.bottomline.dm.core.domain.entity"); factory.setDataSource(rocDataSource); return factory; } @Bean public PlatformTransactionManager rocJpaTransactionManager(EntityManagerFactory rocJpaEntityManagerFactory) { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(rocJpaEntityManagerFactory); return txManager; } }
这个错误是Hibernate解析实体类字段类型时,误将charset当作自定义类型加载导致的,核心原因是实体类注解配置错误,按以下步骤排查修复:
检查@Column注解的columnDefinition属性:遍历所有实体类,查找是否存在
@Column(columnDefinition = "charset")这类错误配置。如果要指定字符集,需写完整的SQL类型定义,比如PostgreSQL环境下:@Column(columnDefinition = "VARCHAR(255) CHARACTER SET utf8")若无需自定义类型,直接移除错误的
columnDefinition参数即可。检查@Type注解配置:如果实体类中使用了
@Type(type = "charset"),这属于错误用法,@Type的type参数应为Hibernate支持的内置类型名(如string、integer)或自定义类型的全限定类名,修正或移除该注解。统一Hibernate版本:错误栈显示实际使用Hibernate 5.6.10,但你声明的是5.6.9,可能是Spring Boot依赖管理自动升级了版本。可在pom.xml中显式锁定版本:
<dependencyManagement> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.6.9.Final</version> </dependency> </dependencies> </dependencyManagement>
内容的提问来源于stack exchange,提问作者Zack Macomber

