添加module-info.java后Hibernate SessionFactory初始化失败求助
问题:模块化项目中Hibernate无法实例化实体持久化器
在普通非模块化项目中实体加载正常,但添加module-info.java后出现如下错误:
Could not instantiate persister org.hibernate.persister.entity.SingleTableEntityPersister
相关代码与配置
module-info.java
module crud.organization { requires jakarta.persistence; requires jakarta.validation; requires org.hibernate.orm.core; requires org.slf4j; requires java.naming;}
Main类加载实体代码
public static void main(String[] args) { OrgCategoryDao orgCategoryDao = new OrgCategoryDao(); Optional<OrgCategory> category = orgCategoryDao.getById(2); if(category.isPresent()) System.err.println("present " + category.get()); else System.err.println("not present");}
HibernateUtil.java
public class HibernateUtil { private final static Logger logger = LoggerFactory.getLogger(HibernateUtil.class); private static StandardServiceRegistry registry = null; private static @NotNull Optional<SessionFactory> sessionFactory = Optional.empty(); private synchronized static @NotNull Optional<SessionFactory> buildSessionFactory() { try { if (registry != null) shutdown(); registry = new StandardServiceRegistryBuilder().configure().build(); MetadataSources sources = new MetadataSources(registry); Metadata metadata = sources.getMetadataBuilder().build(); return Optional.ofNullable(metadata.getSessionFactoryBuilder().build()); } catch (Throwable ex) { System.err.println(ex.getMessage()); shutdown(); } return Optional.empty(); } public synchronized static @NotNull Optional<SessionFactory> getSessionFactory() { if (sessionFactory.isPresent()) return sessionFactory; sessionFactory = buildSessionFactory(); return sessionFactory; } public synchronized static void shutdown() { if(registry != null) { StandardServiceRegistryBuilder.destroy(registry); } }}
OrgCategoryDao.java
public class OrgCategoryDao { public @NotNull Optional<OrgCategory> getById(int id) { final Optional<SessionFactory> factory = HibernateUtil.getSessionFactory(); if(factory.isEmpty()) return Optional.empty(); Session session = null; Transaction transaction = null; try{ session = factory.get().openSession(); transaction = session.beginTransaction(); OrgCategory category = session.get(OrgCategory.class, id); transaction.commit(); return Optional.ofNullable(category); }catch (Exception e){ if(transaction != null){ transaction.rollback(); } logger.error(e.getMessage()); }finally { if(session != null) session.close(); } return Optional.empty(); } }
OrgCategory实体类
@Entity @Table(name = "organization_category") @NamedQuery(name = "getAllWithSortByName", query = "select oc from OrgCategory oc order by name") public class OrgCategory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id_category") private int id; @Column(name = "name_category") private String name; @Column(name = "promt_for_text") private String promtForText; protected OrgCategory() {} public OrgCategory(@NotNull String name, @NotNull String promtForText) { this.name = name; this.promtForText = promtForText; } @Override public String toString() { return "OrganizationCategory{" + "id=" + id + ", name='" + name + '\'' + ", promtForText='" + promtForText + '\'' + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPromtForText() { return promtForText; } public void setPromtForText(String promtForText) { this.promtForText = promtForText; } }
Maven依赖
<dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.5.2.Final</version> </dependency>
解决方案
这个错误的核心原因是模块化环境下,Hibernate无法访问你的实体类。Java模块系统默认隐藏模块内的包,除非显式导出或开放给其他模块。
1. 修改module-info.java
需要导出并开放实体类所在的包给Hibernate模块,让它能识别实体并通过反射访问:
module crud.organization { requires jakarta.persistence; requires jakarta.validation; requires org.hibernate.orm.core; requires org.slf4j; requires java.naming; // 导出实体包,让Hibernate能加载实体类 exports crud.organization.entity to org.hibernate.orm.core; // 开放实体包,允许Hibernate通过反射访问构造方法、字段等 opens crud.organization.entity to org.hibernate.orm.core; }
注意:将crud.organization.entity替换为你实际的实体类所在包路径
2. 显式注册实体类(可选)
如果Hibernate仍无法扫描到实体,可在HibernateUtil的buildSessionFactory方法中显式添加实体:
MetadataSources sources = new MetadataSources(registry) .addAnnotatedClass(OrgCategory.class); // 单个实体类注册 // 若实体较多,可注册整个包 // sources.addPackage("crud.organization.entity");
3. 验证模块路径配置
确保Maven/Gradle正确处理模块化依赖,运行时模块路径包含所有必要的模块。
内容的提问来源于stack exchange,提问作者Asya
相关产品推荐
相关产品推荐

