Java Hibernate创建大量线程并冻结

Java Hibernate创建大量线程并冻结,java,hibernate,Java,Hibernate,我正在构建一个从日志文件读取信息并将这些数据保存到数据库的应用程序。该信息是一组包,其中添加了一些用户,如下所示: Package: (Total: 14, Used: 11) CSHC, 11/11 CTQ8, 11/11 CTQ8, 11/11 休眠会话工厂: public class SessionFactoryUtil { private static SessionFactory sessionFactory; private static S

我正在构建一个从日志文件读取信息并将这些数据保存到数据库的应用程序。该信息是一组包,其中添加了一些用户,如下所示:

Package: (Total: 14, Used: 11) CSHC, 11/11 CTQ8, 11/11 CTQ8, 11/11 休眠会话工厂:

public class SessionFactoryUtil {

    private static SessionFactory sessionFactory;
    private static ServiceRegistry serviceRegistry;

    /**
     * disable constructor to guaranty a single instance
     */
    private SessionFactoryUtil() {
    }

    public static SessionFactory createSessionFactory() {
          Configuration configuration = new Configuration();
          configuration.configure();
          serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
          sessionFactory = configuration.configure().buildSessionFactory(serviceRegistry);
          return sessionFactory;
        }

    public static SessionFactory getSessionFactory() {
        return createSessionFactory();
    }

  /**
   * Opens a session and will not bind it to a session context
   * @return the session
   */
    public Session openSession() {
        return sessionFactory.openSession();
    }

    /**
   * Returns a session from the session context. If there is no session in the context it opens a session,
   * stores it in the context and returns it.
     * This factory is intended to be used with a hibernate.cfg.xml
     * including the following property <property
     * name="current_session_context_class">thread</property> This would return
     * the current open session or if this does not exist, will create a new
     * session
     * 
     * @return the session
     */
    public Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

  /**
   * closes the session factory
   */
    public static void close(){
        if (sessionFactory != null)
            sessionFactory.close();
        sessionFactory = null;

    }
}

问题是对SessionFactoryUtil.getSessionFactory的调用不是单例调用。它每次都创建一个新的会话对象。将该方法修改为真正的单例,使其仅在第一次调用时创建一个新实例

代码完成后,您仍然会遇到无法正确关闭该会话的问题,因此您必须在应用程序结束时调用session.close

编辑

要更改的第一件事是调用getSessionFactory以返回相同的实例:

public static SessionFactory getSessionFactory() {
    //return createSessionFactory();
    return sessionFactory;
}
现在我们只需确保在调用getSessionFactory之前创建sessionFactory。有很多方法可以做到这一点,其中一种更简单的方法是使用静态块,当任何代码第一次调用任何SessionFactoryUtil方法时,将在类加载时调用该块

public class SessionFactoryUtil {

   ...fields declared the same 

   static{
         createSessionFactory();
   }

  ...
}

在看不到其余代码的情况下,我不能确定,但将createSessionFactory设置为私有可能是个好主意,这样其他人就不能覆盖您的sessionFactory实例。

在insertObject对象中,您必须使用try{}最后{close}对不起,我是新加入hibernate的,我不知道如何修改为singleton。我该怎么做?我曾尝试使用此解决方案,但现在它在第一次保存后冻结。现在我尝试使用hibernate.c3p0来管理poool大小和内容,并且在第四次插入数据库后,它给出了,警告:ThreadPoolAsynchronousRunner:730-com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@73cc7a69-正在运行死锁检测器[正在退出。没有挂起的任务。]
public static SessionFactory getSessionFactory() {
    //return createSessionFactory();
    return sessionFactory;
}
public class SessionFactoryUtil {

   ...fields declared the same 

   static{
         createSessionFactory();
   }

  ...
}