java.lang.IllegalStateException:无法在JNDI中找到SessionFactory

时间:2013-05-05 00:44:45

标签: hibernate jsf jndi

晚上好,我在使用带有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>

2 个答案:

答案 0 :(得分:0)

您可以手动将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>

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

希望这有助于某人

答案 1 :(得分:0)

很抱歉这可能是坏消息,但我认为既然没有标记为已回答,也许可以。其他人可能已成为与我相同陷阱的牺牲品。

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

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

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