【问题标题】:java.lang.IllegalStateException: Could not locate SessionFactory in JNDIjava.lang.IllegalStateException:无法在 JNDI 中找到 SessionFactory
【发布时间】:2013-04-29 02:52:38
【问题描述】:

晚上好,我在使用带有 JSF 的 Hibernate 时遇到了上述异常,我过去多次看到它,根本原因是这样的 <session-factory name="sessionFactory"> 所以我删除了名称并更改了生成的代码以创建 SessionFactory从此:

protected SessionFactory getSessionFactory() {
    try {
        return (SessionFactory) new InitialContext()
                .lookup("SessionFactory");
    } catch (Exception e) {
        log.error("Could not locate SessionFactory in JNDI", e);
        throw new IllegalStateException(
                "Could not locate SessionFactory in JNDI");
    }
}

到那个:

protected SessionFactory getSessionFactory() {
    try {
        return new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
    } catch (Exception e) {
        log.error("Could not locate SessionFactory in JNDI", e);
        throw new IllegalStateException(
                "Could not locate SessionFactory in JNDI");
    }
}

对我来说工作正常,但是这次我没有解决它,你知道问题出在哪里吗?

hibernate-cfg.xml

<hibernate-configuration>
<session-factory>
    <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/GUNO</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.search.autoregister_listeners">false</property>
</session-factory>

【问题讨论】:

    标签: hibernate jndi


    【解决方案1】:

    很抱歉删除了这个,但我认为既然没有标记为已回答,也许它会没问题。其他人可能和我一样陷入了同样的陷阱。

    我最近在合并一些 HBM 后遇到了类似的问题。随后,由于 HBM 文件中的重复类映射导致 JNDI/SessionFactory 服务无法启动,我遇到了有关 JNDI 和 sessionFactory 查找失败的问题。

    所以,作为开始 - 确保您没有在映射文件中声明重复的类 :)

    这可能是看这个问题的人所需要的,也可能不是,但这是我的问题:)

    【讨论】:

      【解决方案2】:

      您可以手动将 SessionFactory 添加到 Context。 虽然看起来很多代码,但实际上只有这 5 行代码。剩下的只是处理 InitialContext 似乎喜欢抛出的 NamingException。

      更好的方法是使用 ContextListener 在启动期间自动添加会话

      InitialContext initialContext = new InitialContext();
      SessionFactory sf = (SessionFactory)  initialContext.lookup("SessionFactory");
      Configuration cfg = new Configuration();
      cfg.configure();
      sf = cfg.buildSessionFactory();
      initialContext.bind("SessionFactory", sf);
      

      这里是完整的 Servlet goGet 方法

          protected void doGet(HttpServletRequest request,
              HttpServletResponse response) throws ServletException, IOException {
          Account acc;
          InitialContext initialContext = null;
          acc = new Account("asdf" + String.valueOf(new Date().getTime()), "asdf");
          AccountHome home;
          Transaction tx = null;
          SessionFactory sf;
      
                  // Create an instance of the InitialContext
                  // So that we can lookup the SessionFactory property
                  // or add it if it does not yet exist
          try {
      
              initialContext = new InitialContext();
      
          } catch (NamingException e) {
              throw new ServletException("Unable to create InitalContext", e);
          }
      
                  // Since SessionFactories are very expensive to create 
                  // first attempt to lookup a cached instance of the SessionFactory
          try {
              sf = (SessionFactory) initialContext.lookup("SessionFactory");
          } catch (NamingException e) {
                          // There is currently no session factory bound to this context
                          // Manually create it and bind it
              Configuration cfg;
              cfg = new Configuration();
              cfg.configure();
              sf = cfg.buildSessionFactory();
      
              try {
                  initialContext.bind("SessionFactory", sf);
              } catch (NamingException e1) {
                  throw new ServletException(
                          "Unable to bind the SessionFactory to the Inital Context");
              }
          }
      
                  // Start the transaction and perform work
          tx = sf.getCurrentSession().beginTransaction();
          try {
              home = new AccountHome();
              home.persist(acc);
              tx.commit();
          } catch (Exception e) {
              tx.rollback();
              throw new ServletException("Work failed", e);
          }
      
      }
      

      编辑:添加 ContextListener

      package ch.yaawi.platform;
      
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import javax.servlet.ServletContextEvent;
      import javax.servlet.ServletContextListener;
      
      import org.hibernate.SessionFactory;
      import org.hibernate.cfg.Configuration;
      
      public class SessionFactoryListener implements ServletContextListener {
      
      private SessionFactory mSessionFactory;
      
      public void contextDestroyed(ServletContextEvent event) {
      
          if (mSessionFactory != null && !mSessionFactory.isClosed()) {
              mSessionFactory.close();
          }
      
      }
      
      public void contextInitialized(ServletContextEvent event) {
          InitialContext initialContext = null;
          try {
      
              initialContext = new InitialContext();
      
          } catch (NamingException e) {
              throw new RuntimeException("Unable to create InitalContext", e);
          }
      
          try {
              mSessionFactory = (SessionFactory) initialContext
                      .lookup("SessionFactory");
          } catch (NamingException e) {
              Configuration cfg;
              cfg = new Configuration();
              cfg.configure();
              mSessionFactory = cfg.buildSessionFactory();
      
              try {
                  initialContext.bind("SessionFactory", mSessionFactory);
              } catch (NamingException e1) {
                  throw new RuntimeException(
                          "Unable to bind the SessionFactory to the Inital Context");
              }
          }
      
      }
      
      }
      

      然后在你的 web.xml 中

      <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
      
      <web-app>
      <display-name>Archetype Created Web Application</display-name>
      
      <listener>
          <listener-class>ch.yaawi.platform.SessionFactoryListener</listener-class>
      </listener>
      
      </web-app>
      

      导致将命名空间更改为您自己的。

      希望这对某人有所帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-25
        • 2014-06-10
        • 2010-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 2014-05-23
        相关资源
        最近更新 更多