Spring Boot中SessionFactory Bean创建失败,ClassFormatException问题求助
首先,核心异常是org.springframework.core.type.classreading.ClassFormatException,这个异常一般和字节码损坏、依赖版本不兼容或类文件问题有关,但你的配置类里先有几个明显的低级错误,先把这些修正再排查其他问题:
1. 配置文件读取逻辑完全错误
你的dataSource()方法把配置值直接当成了env.getProperty()的参数,这完全搞反了!getProperty()的参数是配置文件中的key,不是值本身。
修正方法:
先在application.properties中配置数据库信息:
spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost:5432/m4BD spring.datasource.username=你的数据库用户名 spring.datasource.password=你的数据库密码
然后在配置类中读取这些key:
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name")); dataSource.setUrl(env.getProperty("spring.datasource.url")); dataSource.setUsername(env.getProperty("spring.datasource.username")); dataSource.setPassword(env.getProperty("spring.datasource.password"));
2. 实体类扫描包路径错误
你写的扫描包是com.baeldung.hibernate.bootstrap.model,但你的项目实际包是com.lyuban.m4banktask,这明显是抄示例代码没修改!Spring扫不到你的实体类必然引发后续错误。
修正方法:
换成你自己项目中实体类所在的包路径:
sessionFactory.setPackagesToScan(new String[]{"com.lyuban.m4banktask.model"});
3. 事务管理器依赖注入方式错误
你在hibernateTransactionManager()中直接调用sessionFactory().getObject(),这会创建一个新的LocalSessionFactoryBean实例,根本不是Spring容器管理的Bean,导致依赖关系混乱。
修正方法:
让Spring注入容器中已初始化好的SessionFactory:
@Bean public PlatformTransactionManager hibernateTransactionManager(SessionFactory sessionFactory) { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(sessionFactory); return transactionManager; }
4. 版本不兼容(ClassFormatException的核心原因)
你使用的是Spring Boot 3.1.9,但配置里用的是spring-orm.hibernate5相关类!Spring Boot 3.x要求搭配Hibernate 6,Hibernate 5与Spring Boot 3存在严重的版本不兼容,这大概率是字节码异常的根源。
修正方法:
把Hibernate相关的类替换为6.x版本的:
- 替换
org.springframework.orm.hibernate5.LocalSessionFactoryBean为org.springframework.orm.hibernate6.LocalSessionFactoryBean - 替换
org.springframework.orm.hibernate5.HibernateTransactionManager为org.springframework.orm.hibernate6.HibernateTransactionManager
5. 其他排查方向(若上述修正后仍报错)
- 清理编译目录:删除
target或build文件夹,重新编译项目,避免损坏的字节码文件残留 - 检查实体类:确认实体类没有语法错误,比如Lombok注解使用不当导致字节码生成异常
- 对齐JDK版本:确保编译和运行环境都用JDK 17+,Spring Boot 3.x强制要求JDK 17及以上
修正后的完整配置类示例
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.orm.hibernate6.HibernateTransactionManager; import org.springframework.orm.hibernate6.LocalSessionFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; import java.util.Properties; @Configuration @EnableTransactionManagement public class HibernateConf { private final Environment env; public HibernateConf(Environment env) { this.env = env; } @Bean public LocalSessionFactoryBean sessionFactory() { LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(dataSource()); sessionFactory.setPackagesToScan(new String[]{"com.lyuban.m4banktask.model"}); sessionFactory.setHibernateProperties(hibernateProperties()); return sessionFactory; } @Bean public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name")); dataSource.setUrl(env.getProperty("spring.datasource.url")); dataSource.setUsername(env.getProperty("spring.datasource.username")); dataSource.setPassword(env.getProperty("spring.datasource.password")); return dataSource; } @Bean public PlatformTransactionManager hibernateTransactionManager(SessionFactory sessionFactory) { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(sessionFactory); return transactionManager; } private Properties hibernateProperties() { Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update"); hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); return hibernateProperties; } }
内容的提问来源于stack exchange,提问作者Stasis2

