【问题标题】:Creating sessionFactory in Hql-Initialization在 Hql-Initialization 中创建 sessionFactory
【发布时间】:2013-01-29 09:19:17
【问题描述】:

我已经创建了一个 dbadapter 用于 delaing with hibernate。实际上我的类看起来像这样..

 public class DBAdapter {
    private static SessionFactory factory;
        private static final ThreadLocal<Session> threadSession = new ThreadLocal(); 

        public static Session OpenConnection() {
      if (factory == null) {
       factory = new Configuration().configure(
       "com/et/hibernatexml/hibernate.cfg.xml")
      .buildSessionFactory();
      }
     Session s = (Session) threadSession.get(); 
         if (s == null)
         { 
            s =factory.openSession(); 
            threadSession.set(s); 
          } 
        return s; 
 }
 public List selectQuery(String QueryString)
  {   try
      {
       Session session=OpenConnection();
       resultlist = query.list();
       }
       finally()
       {
        closeSession();
       }
   }
    public static void closeSession()
    {
      Session session = (Session) threadSession.get(); 
      threadSession.set(null); 
      if (session != null && session.isOpen()) { 
          session.flush(); 
          session.close(); 
      } 
}

为了从服务器获取数据,我会这样做..

   DBAdapter ob=new DBAdapter();
   ob.setParameter("orgId", orgId);
   List list=ob.selectQuery(queryvalue);

我怀疑这样处理有什么问题。特别是因为 SessionFactory 是静态变量??

【问题讨论】:

标签: java hibernate static thread-safety sessionfactory


【解决方案1】:

您不希望多个线程创建会话工厂。它应该是一个单例,并且在设计上是线程安全的。使用您提供的代码执行此操作的最简单方法是在 openConnection() 方法上使用 synchronized 关键字。但是,没有理由同步创建会话的部分代码并将其也放在 ThreadLocal 实例上。一个粗略的解决方案如下所示

public class DBAdapter {
    private static SessionFactory factory;
    private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>(); 

    private static synchronized SessionFactory getSessionFactory() {
        if(factory == null) {
            factory = new Configuration().configure("com/et/hibernatexml/hibernate.cfg.xml").buildSessionFactory();
        }
        return factory;
    }

    public static Session getSession() {
        Session s = (Session) threadSession.get(); 
        if (s == null) { 
            s = getSessionFactory().openSession(); 
            threadSession.set(s); 
        } 
        return s; 
     }
}

【讨论】:

  • 我的主要疑问是每次创建DBAdapter对象的对象时,它会创建工厂吗??..还是只有一次??
  • DBAdapter 类是一个只有静态方法的实用程序类。无需创建它的实例。无论哪种方式,此类的实例创建都不会运行静态初始化程序。 ThreadLocal 将在 JVM 第一次加载此类时创建,而 SessionFactory 将在线程第一次尝试获取 Session 时创建。我会温和地建议您阅读一本好的 Java 手册,例如 Kathy Sierra 的 SCJP6。
  • 目前我在 DBadapter 中有一个方法“public List selectQuery”。那也是静态方法???
  • 也可以。但是我会稍微模块化代码。还要在 try/finally 中添加一个 catch 块。理想情况下,您也希望实现事务管理...无论如何,您已经有了一个不错的开始,继续挖掘。
  • @dkateros..非常感谢你..如果我有任何疑问我会问..正确测试后,我会将您的评论标记为答案..
猜你喜欢
  • 1970-01-01
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
  • 2014-02-26
  • 2020-04-21
  • 2019-08-16
  • 2012-07-07
  • 1970-01-01
相关资源
最近更新 更多