java.lang.IllegalStateException: Could not locate SessionFactory in JNDI

笑着哭i 提交于 2019-12-02 10:13:05

You could manually add the SessionFactory to the Context. Although it looks like a lot of code it is really only these 5 lines. The rest is just handeling the NamingException which InitialContext seems to love throwing.

A better approach would be to use a ContextListener to automatically add the session during start up

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

Here is the full Servlet goGet method

    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);
    }

}

EDIT: Added 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");
        }
    }

}

}

Then in your 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>

Of causing changing the namespace to your own.

Hope this helps someone

Sorry to necro this, but I thought that since this wasn't marked as answered perhaps it would be OK. Others may have fallen victim to the same pitfall as I.

I recently ran into similar problems after merging some HBM's. Subsequently, I had issues regarding JNDI and sessionFactory look-up failures due to duplicate class mappings in the HBM files causing the JNDI/SessionFactory service to be unable to start up..

So, as a start - make sure you are not declaring duplicate classes in your mapping files :)

This may or may not be what someone looking at this question needs, but it was my issue :)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!