Good evening, i get the above exception when using Hibernate with JSF, i saw it many times in the past and the root cause was that like this <session-factory name="sessionFactory">
so i removed the name and change the generated code for creating the SessionFactory from that:
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");
}
}
to that:
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");
}
}
it was working fine with me, but this time i have no solution to it, do you know where the problem resides?
the 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>
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 :)