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

Hibernate 4.3.1 单例SessionFactory无法正常使用问题咨询

问题原因与修复方案

核心错误点

  • 类型使用错误:SFController.getSessionFactory() 方法返回的是SessionFactory类型,你直接将其赋值给Session类型的变量,必然会触发类型不匹配提示。SessionFactory是会话工厂,本身不具备save()、beginTransaction()等数据操作方法,这些方法是Session接口的能力。
  • 缺少Session获取步骤:你需要从SessionFactory实例中调用openSession()或者getCurrentSession()方法,才能拿到可用于数据操作的Session对象。

代码修复

1. 可选优化:SFController单例线程安全修复

原有实现为非线程安全的懒汉单例,高并发场景下可能生成多个实例,优化后代码如下:

package Controller;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class SFController {

    // 加volatile禁止指令重排
    private static volatile SFController instance = null;
    private SessionFactory sessionFactory;
    private StandardServiceRegistry serviceRegistry;

    private SFController(){
        Configuration configuration = new Configuration();
        configuration.configure();
        serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    }

    // 双重校验锁实现线程安全的懒汉单例
    public static SFController getInstance(){
        if(instance == null){
            synchronized (SFController.class) {
                if (instance == null) {
                    instance  = new SFController();
                }
            }
        }
        return instance;
    }

    // 去掉static修饰,符合单例工具类的常规设计逻辑
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

2. 业务调用代码修复

package Controller;

import org.hibernate.Session;
import org.hibernate.Transaction;

public class TryObject {
    public void testDataOperate() {
        // 1. 获取单例实例,拿到SessionFactory
        SFController sfController = SFController.getInstance();
        // 2. 从SessionFactory获取可操作的Session对象
        Session session = sfController.getSessionFactory().openSession();
        // 3. 正常调用数据操作方法
        Transaction tx = session.beginTransaction();
        // 示例:保存你的POJO对象
        // YourPOJO pojo = new YourPOJO();
        // session.save(pojo);
        tx.commit();
        // 手动打开的Session使用完后需要关闭
        session.close();
    }
}

补充说明

如果你的Hibernate配置文件中添加了hibernate.current_session_context_class配置项,也可以调用getCurrentSession()方法获取和当前线程绑定的Session,不需要手动关闭,事务提交后会自动释放资源。

内容的提问来源于stack exchange,提问作者user023835

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:27:01