Hibernate 5报错java.lang.NoSuchMethodError: javax.persistence.Table.indexes()求助
我看了你遇到的问题——用Hibernate注解测试POJO时,buildSessionFactory()一直报错,而且配置在另一个项目能用、JDBC连接也没问题,确实挺闹心的。我帮你梳理几个最可能的问题点,你可以逐一排查:
1. 先修正最容易忽略的HQL语句错误
你在测试类里写的查询语句是:
session.createQuery("from items").list();
注意HQL是面向实体类的查询语言,不是直接用数据库表名。你的实体类名为Item,所以正确的写法应该是:
session.createQuery("from Item").list();
更规范的类型安全写法可以改成:
session.createQuery("SELECT i FROM Item i", Item.class).list();
虽然这个错误更多是后续查询阶段的问题,但有时候Hibernate在预解析查询时也会影响SessionFactory的初始化,先把它修正。
2. 解决JPA API jar包冲突(核心可能原因)
你当前引入的依赖里同时存在两个JPA API相关的jar包:
hibernate-jpa-2.0-api-1.0.0.Final.jarjavax.persistence-api-2.2.jar
Hibernate 5.3.0.Final是完全支持JPA 2.2规范的,同时引入旧版的JPA API会导致类加载冲突,这大概率是buildSessionFactory()报错的根源。你需要删除hibernate-jpa-2.0-api-1.0.0.Final.jar,只保留javax.persistence-api-2.2.jar即可。
3. 改用Hibernate 5.x推荐的SessionFactory构建方式
Hibernate 5.x开始,Configuration.buildSessionFactory()已经被标记为过时,官方推荐使用标准服务注册的方式构建SessionFactory,这样能避免一些初始化时的潜在问题。你可以把测试类的代码改成:
public static void main(String[] args) { // 构建标准服务注册 StandardServiceRegistry registry = new StandardServiceRegistryBuilder() .configure("hibernate.cfg.xml") .build(); SessionFactory factory = null; try { // 通过MetadataSources构建SessionFactory factory = new MetadataSources(registry) .addAnnotatedClass(Item.class) .buildMetadata() .buildSessionFactory(); // 后续Session操作 Session session = factory.getCurrentSession(); session.beginTransaction(); List<Item> items = session.createQuery("from Item", Item.class).list(); // 这里可以添加遍历输出等操作 for(Item item : items) { System.out.println(item); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); // 出错时销毁服务注册 StandardServiceRegistryBuilder.destroy(registry); } finally { if(factory != null) { factory.close(); } } }
4. 确认实体类的完整性
虽然你提到已经有getter和setter,但还是要再检查:
Item类的所有字段(id、name、price、stock)都有public的getter和setter方法- 实体类是public修饰的,且没有被final修饰(Hibernate需要生成代理类,final类会导致初始化失败)
额外提示
如果以上几点都修正后还是报错,建议你把完整的错误堆栈信息贴出来,这样能更精准定位问题——比如可能是hibernate.cfg.xml里的方言配置不对(你用的是MySQL 8.0驱动,对应的方言应该是org.hibernate.dialect.MySQL8Dialect,而不是旧的MySQL5Dialect)。
内容的提问来源于stack exchange,提问作者JeanPierre

