使用Hibernate Criteria API时出现“Not an entity”错误求助
解决Hibernate Criteria API抛出"Not an entity"错误的问题
问题场景
在Java8 + Hibernate5.6.5的项目中,使用Criteria API执行查询时,Root<WaDAO> root = criteria.from(WaDAO.class);代码行持续抛出java.lang.IllegalArgumentException: Not an entity错误。
可能原因
- SessionFactory构建逻辑错误:Hibernate 5.x中旧的
Configuration.buildSessionFactory方式可能无法正确加载配置文件中的实体映射,导致WaDAO未被注册为实体。 - 实体映射配置问题:
hibernate.cfg.xml中的实体类路径拼写错误,或者实体类注解导入错误。 - 类加载器冲突:WaDAO类被多个类加载器加载,导致Hibernate无法识别为已注册的实体类型。
解决方法
方法1:修正SessionFactory构建逻辑(优先尝试)
修改HibernateUtil的buildSessionFactory方法,使用Hibernate 5.x官方推荐的MetadataSources和Metadata构建流程,确保实体映射被正确加载:
package com.aeon.prov.ddd.infrastructure.base; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; public class HibernateUtil { private static SessionFactory sessionFactory; private static SessionFactory buildSessionFactory() { try { // 加载hibernate.cfg.xml并构建服务注册器 StandardServiceRegistry registry = new StandardServiceRegistryBuilder() .configure("hibernate.cfg.xml") .build(); // 通过MetadataSources加载实体映射元数据 Metadata metadata = new MetadataSources(registry) .getMetadataBuilder() .build(); // 构建SessionFactory sessionFactory = metadata.buildSessionFactory(); System.out.println("SessionFactory 创建成功"); return sessionFactory; } catch (Throwable ex) { System.out.println("SessionFactory 初始化失败: " + ex); ex.printStackTrace(); StandardServiceRegistryBuilder.destroy(registry); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { if(sessionFactory == null) sessionFactory = buildSessionFactory(); return sessionFactory; } }
方法2:验证实体映射配置
- 检查
hibernate.cfg.xml中的实体映射路径是否完全匹配WaDAO的包名和类名:
确保无大小写、拼写错误。<mapping class="com.aeon.prov.ddd.infrastructure.workflow.WaDAO"/> - 确认WaDAO类的
@Entity注解导入的是javax.persistence.Entity,而非其他包下的同名注解。
方法3:排查类加载器冲突
如果项目使用了自定义类加载器或模块化框架,添加日志打印类加载器信息,确认实体类和Hibernate核心类的类加载器一致:
// 在WorkflowHibernateRepo的findAll方法中添加 System.out.println(WaDAO.class.getClassLoader()); System.out.println(session.getClass().getClassLoader());
若两者不同,调整类加载策略,确保实体类被Hibernate的类加载器加载。
方法4:显式注册实体类
如果上述方法无效,在HibernateUtil中显式添加实体类映射,强制Hibernate识别:
Metadata metadata = new MetadataSources(registry) .addAnnotatedClass(WaDAO.class) // 显式注册实体类 .getMetadataBuilder() .build();
验证步骤
- 运行修改后的代码,调用
findAll方法检查错误是否消失。 - 若之前注释的HQL版本
findAll可以正常运行,说明实体本身有效,优先通过方法1解决问题。
内容的提问来源于stack exchange,提问作者Mario Daglio
相关产品推荐
相关产品推荐

