迁移至Hibernate 6.1.6与spring-orm 6.0时遇Criterion类找不到异常
问题根源
org.hibernate.criterion.Criterion是Hibernate旧版Criteria API的核心类,Hibernate 6.x已彻底移除这套API,而你使用的HibernateTemplate内部仍在尝试加载这个已被移除的类,导致抛出ClassNotFoundException。尽管Spring Framework 6.0兼容Hibernate 6.x,但HibernateTemplate本身在Spring中早已被标记为过时(从Spring 3.x开始就不推荐使用),其针对Hibernate 6.x的适配并未完全移除对旧Criteria API的依赖,或者你的代码中存在隐性引用。
解决方案
1. 排查代码中的隐性依赖
全局搜索项目代码,确认是否直接引用了org.hibernate.criterion.*包下的类(比如Criteria、Restrictions等),这些类在Hibernate 6.x中已全部移除,需要替换为JPA标准的Criteria API(jakarta.persistence.criteria.*)或者HQL/JPQL。
2. 替换HibernateTemplate为原生API
由于HibernateTemplate过时且存在兼容性问题,建议直接使用Hibernate原生Session或JPA EntityManager替代:
- 使用Hibernate Session示例:
@Autowired private SessionFactory sessionFactory; public void queryEntity() { try (Session session = sessionFactory.openSession()) { // HQL查询 List<Entity> result = session.createQuery("from Entity where id = :id", Entity.class) .setParameter("id", 1L) .list(); // 持久化操作 session.beginTransaction(); session.save(new Entity()); session.getTransaction().commit(); } }
- 使用JPA EntityManager示例:
@PersistenceContext private EntityManager entityManager; public void queryEntity() { // JPQL查询 List<Entity> result = entityManager.createQuery("select e from Entity e where e.id = :id", Entity.class) .setParameter("id", 1L) .getResultList(); // 持久化操作 entityManager.getTransaction().begin(); entityManager.persist(new Entity()); entityManager.getTransaction().commit(); }
3. 确保版本完全匹配
确认spring-orm版本为6.0.x及以上,与Hibernate 6.1.6.Final完全兼容。构建文件中明确指定版本:
- Maven示例:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>6.0.15</version> <!-- 与Spring Framework 6.x版本一致 --> </dependency> <dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <version>6.1.6.Final</version> </dependency>
关键提醒
Hibernate 6.x对旧API的兼容性改动极大,除Criteria API外,org.hibernate.Query、Session.createCriteria()等旧特性也已被移除或替换,迁移时需逐一替换这些过时用法,才能彻底解决兼容性问题。
内容的提问来源于stack exchange,提问作者Karuna

