You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 17:53:12