Spring创建hibernateTemplate Bean失败:缺失org.hibernate.criterion.Criterion类
问题:Spring整合Hibernate时
hibernateTemplate Bean创建失败 异常信息
创建在com.spring.Config中定义的名为'hibernateTemplate'的Bean失败:无法实例化[org.springframework.orm.hibernate5.HibernateTemplate]:工厂方法'hibernateTemplate'抛出异常,消息:org/hibernate/criterion/Criterion 线程"main"中的异常:org.springframework.beans.factory.BeanCreationException:创建在com.spring.Config中定义的名为'hibernateTemplate'的Bean失败:无法实例化[org.springframework.orm.hibernate5.HibernateTemplate]:工厂方法'hibernateTemplate'抛出异常,消息:org/hibernate/criterion/Criterion at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:648)
配置类Config代码
@Configuration public class Config { @Bean public DriverManagerDataSource getDataSource() { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/todo"); ds.setUsername("root"); ds.setPassword("root"); return ds; } @Bean public SessionFactory sessionFactory() { LocalSessionFactoryBean factory = new LocalSessionFactoryBean(); factory.setDataSource(getDataSource()); Properties prop = new Properties(); prop.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect"); prop.setProperty("hibernate.show_sql", "true"); prop.setProperty("hibernate.hbm2ddl.auto", "update"); factory.setHibernateProperties(prop); factory.setAnnotatedClasses(Student.class); return factory.getObject(); } @Bean public HibernateTemplate hibernateTemplate() { return new HibernateTemplate(sessionFactory()); } }
主类App代码
public class App { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(Config.class); HibernateTemplate st = (HibernateTemplate)context.getBean("hibernateTemplate"); System.out.println(st); } }
解决方案
1. 核心原因
org.hibernate.criterion.Criterion是Hibernate 5.2版本之前的API,5.2及以上版本已移除该类。出现错误是因为你使用的Hibernate版本(5.2+)与Spring的HibernateTemplate依赖的API不兼容,同时当前SessionFactory的创建逻辑也存在问题。
2. 具体修复步骤
(1)修复SessionFactory的创建逻辑
当前sessionFactory()方法直接调用factory.getObject()是错误的,LocalSessionFactoryBean是FactoryBean,需要由Spring容器完成初始化,直接调用getObject()会返回未初始化的实例。修改配置类:
@Configuration public class Config { @Bean public DriverManagerDataSource getDataSource() { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/todo"); ds.setUsername("root"); ds.setPassword("root"); return ds; } // 让Spring管理LocalSessionFactoryBean的生命周期 @Bean public LocalSessionFactoryBean localSessionFactoryBean() { LocalSessionFactoryBean factory = new LocalSessionFactoryBean(); factory.setDataSource(getDataSource()); Properties prop = new Properties(); prop.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect"); prop.setProperty("hibernate.show_sql", "true"); prop.setProperty("hibernate.hbm2ddl.auto", "update"); factory.setHibernateProperties(prop); factory.setAnnotatedClasses(Student.class); return factory; } // 通过Spring注入LocalSessionFactoryBean,获取初始化完成的SessionFactory @Bean public SessionFactory sessionFactory(LocalSessionFactoryBean localSessionFactoryBean) { return localSessionFactoryBean.getObject(); } // 依赖注入SessionFactory创建HibernateTemplate @Bean public HibernateTemplate hibernateTemplate(SessionFactory sessionFactory) { return new HibernateTemplate(sessionFactory); } }
(2)调整Hibernate版本(可选)
如果修复后仍出现API缺失问题,需将Hibernate版本降级到5.1.x及以下,确保与Spring ORM的HibernateTemplate兼容。例如Maven依赖配置:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.1.17.Final</version> </dependency>
(3)推荐方案:弃用HibernateTemplate
HibernateTemplate已属于Spring的过时API,官方推荐直接使用Hibernate原生SessionFactory或EntityManager,或者改用Spring Data JPA来简化数据操作,避免版本兼容问题。
内容的提问来源于stack exchange,提问作者user19495396
相关产品推荐
相关产品推荐

