如何在Hibernate 4.3.4.Final中配置和获取会话?

Jac*_*ack 8 java configuration hibernate transactions c3p0

我最近将我的Hibernate版本升级到4.3.4.Final.基于Hibernate的Contextual Sessions配置,这个新版本不再基于ThreadLocal.如果我到目前为止所做的是正确的,我是否需要做任何事情来提高效率?如果不正确我该怎么办?我没有线索.

请注意,文档中提到:Hibernate提供了三种当前会话跟踪方法.基于"线程"的方法不适用于生产用途; 它仅适用于原型设计和教程,例如本教程.

的hibernate.cfg.xml

<hibernate-configuration>

    <session-factory>

    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost/myDB</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- Disable the second-level cache  -->
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

    <property name="show_sql">true</property>

    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.timeout">300</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.idle_test_period">3000</property>
        <!--        <property name="hbm2ddl.auto">update</property>-->

        <mapping class="com.myProject.entities.users" />
        ...
Run Code Online (Sandbox Code Playgroud)

当前配置和代码

基于答案吹响和这部分文档 mu当前配置如下:

 public class HibernateUtil {

    private static SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
              Configuration configuration = new Configuration();
              return configuration.configure()
                                  .buildSessionFactory(
                                       new StandardServiceRegistryBuilder()  
                                          .applySettings(configuration.getProperties())
                                          .build());
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

}
Run Code Online (Sandbox Code Playgroud)

代码如下

    final Session session = HibernateUtil.getSessionFactory().openSession();
    try {
        final Transaction tx = session.beginTransaction();
        try {
              ...
Run Code Online (Sandbox Code Playgroud)

以前的配置和代码

public class HibernateUtil {

    private static ServiceRegistry serviceRegistry;
    private static final ThreadLocal<Session> threadLocal = new ThreadLocal();
    private static SessionFactory sessionFactory;

    private static SessionFactory configureSessionFactory() {
        try {
            Configuration configuration = new Configuration();
            configuration.configure();
            serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties())
                    .build();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            return sessionFactory;
        } catch (HibernateException e) {
            System.out.append("** Exception in SessionFactory **");
            e.printStackTrace();
        }
        return sessionFactory;
    }

    static {
        try {
            sessionFactory = configureSessionFactory();
        } catch (Exception e) {
            System.err.println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }
    }

    private HibernateUtil() {
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static Session getSession() throws HibernateException {
        Session session = threadLocal.get();

        if (session == null || !session.isOpen()) {
            if (sessionFactory == null) {
                rebuildSessionFactory();
            }
            session = (sessionFactory != null) ? sessionFactory.openSession() : null;
            threadLocal.set(session);
        }

        return session;
    }

    public static void rebuildSessionFactory() {
        try {
            sessionFactory = configureSessionFactory();
        } catch (Exception e) {
            System.err.println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }
    }

    public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);
        if (session != null) {
            if (session.isOpen()) {
                session.close();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用于访问事务和提交命令的代码

 final Session session = HibernateUtil.getSession();
        try {
            final Transaction tx = session.beginTransaction();
            try {

                    //Commands related to query go here

             if (!tx.wasCommitted()) {
                    tx.commit();
                }

                if (session.isOpen()) {
                    session.close();
                }

                return true;
            } catch (Exception e) {
                tx.rollback();
                return false;
            }
        } finally {
            HibernateUtil.closeSession();
        }
        return false;
Run Code Online (Sandbox Code Playgroud)

van*_*kel 2

只需访问应用程序中 SessionFactory 的单个实例即可。

以下信息均来自 Hibernate 4.3 手册第 2.2 章(可获取)。上下文会话13. 事务和并发

SessionFactory是一个创建成本高昂的线程安全对象,旨在由所有应用程序线程共享。它通常在应用程序启动时从 Configuration 实例创建一次。”
会话是一种廉价的、非线程安全的对象,应该使用一次,然后丢弃:单个请求、对话或单个工作单元。”

如果没有“工作单元”而只有一堆(捆绑的)查询和更新,只需遵循非托管环境的第一个习惯用法(来自前面提到的第 13 章)。除非你能证明这会带来性能问题(*),否则不要尝试优化,因为这是万恶之源

如果存在“工作单元”或“每个请求的会话”,则HibernateUtil可以使用org.hibernate.context.internal.ThreadLocalSessionContextas (参见前面提到的第 2.2 章)并遵循非托管环境CurrentSessionContext的第二个习惯用法来替换问题中的。

如果您使用 JTA,请替换ThreadLocalSessionContext为并遵循使用 JTAorg.hibernate.context.internal.JTASessionContext中描述的习惯用法。

请注意讨论“工作单元”的章节:良好的软件架构取决于对“业务事务”和“应用程序事务”对应用程序意味着什么的良好理解。

(*) 性能问题可能是由配置问题引起的,例如这个问题在 Hibernate 手册中相关文档 。

  • 我仍然有点困惑,但我可以解决问题并访问 getCurrentSession 方法,问题现在已更新。 (2认同)