Java 在Hql初始化中创建sessionFactory

Java 在Hql初始化中创建sessionFactory,java,hibernate,static,thread-safety,sessionfactory,Java,Hibernate,Static,Thread Safety,Sessionfactory,我已经创建了一个dbadapter,用于使用hibernate进行delaing public class DBAdapter { private static SessionFactory factory; private static final ThreadLocal<Session> threadSession = new ThreadLocal(); public static Session OpenConnection()

我已经创建了一个dbadapter,用于使用hibernate进行delaing

 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是静态变量???

您不希望有多个线程来创建会话工厂。它应该是一个单例,并且设计为线程安全的。使用您提供的代码执行此操作的最简单方法是在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{
私营静电厂;
private static final ThreadLocal threadSession=new ThreadLocal();
私有静态同步SessionFactory getSessionFactory(){
如果(工厂==null){
factory=new Configuration().configure(“com/et/hibernatexml/hibernate.cfg.xml”).buildSessionFactory();
}
返回工厂;
}
公共静态会话getSession(){
会话s=(会话)threadSession.get();
如果(s==null){
s=getSessionFactory().openSession();
threadSession.set(个);
} 
返回s;
}
}

您至少应该同步OpenConnection()方法。SessionFactory是静态的没有问题,它应该是单例的,因为它的制作成本很高。你能通过添加示例代码来澄清吗??哪一个应该是独生子女??DBAdapter类??另外,我也不清楚术语“同步”我的主要疑问是,每次创建DBAdapter对象的对象时,它都会创建工厂???。或者它只是一次??类DBAdapter是一个只有静态方法的实用程序类。永远不需要创建它的实例。无论哪种方式,此类的实例创建都不会运行静态初始值设定项。当JVM第一次加载此类时,将创建ThreadLocal;当线程第一次尝试获取会话时,将创建SessionFactory。我温和地建议您阅读一本好的java手册,比如Kathy Sierra编写的SCJP6。目前,我在DBadapter中有一个方法“public List selectQuery”。这也是一种静态方法???也可能是。不过,我会将代码模块化一点。还向try/finally添加一个catch块。理想情况下,您也希望实现事务管理。。。不管怎样,你已经有了一个良好的开端,继续挖掘。@dkateros。非常感谢。如果我有任何疑问,我会问。正确测试后,我会将你的评论标记为答案。。