2013-05-05 113 views
0

晚上好,我在使用Hibernate和JSF时遇到了上述异常,我在过去多次看到它,根本原因是这样<session-factory name="sessionFactory">因此我删除了命名和更改生成的代码与创建了一个SessionFactory:java.lang.IllegalStateException:无法在JNDI中找到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> 

回答

0

你可以把SessionFactory手动添加到上下文。 虽然它看起来像很多代码,但实际上只有这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> 

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

希望这可以帮助别人

0

抱歉死灵这一点,但我想,既然作为回答了这个没有标记也许会确定。其他人可能曾被人以同样的陷阱作为一

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

因此,作为开始 - 确保您不要在你的映射文件中声明重复的类:)

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

相关问题