Tomcat 文档说:
Tomcat 提供了只读的InitialContext,而 Hibernate 需要读写才能管理多个会话工厂。Tomcat 显然遵循非托管容器的规范。如果您想将会话工厂绑定到 JNDI 对象,您要么必须移动到托管服务器(Glassfish、JBoss 等),要么在 Internet 上搜索一些已发布的解决方法。
Hibernate 文档的建议是在hibernate.session_factory_name使用 Tomcat 时忽略该属性,不要尝试绑定到 JNDI。
Hibernate 文档也这么说:
将 SessionFactory 绑定到 JDNI 命名空间非常有用。在大多数情况下,这可以hibernate.session_factory_name
在您的配置中使用属性。但是,对于 Tomcat,您不能使用
hibernate.session_factory_name属性,因为 Tomcat 提供了只读的 JNDI 实现。要在 Tomcat 中使用 JNDI 绑定SessionFactory,您应该为 Tomcat 编写自定义资源工厂类
SessionFactory并对其进行设置。
所以你需要SessionFactory像这样定制:
package myutil.hibernate;
import java.util.Hashtable;
import java.util.Enumeration;
import javax.naming.Name;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.RefAddr;
import javax.naming.spi.ObjectFactory
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactoryTomcatFactory implements ObjectFactory{
public Object getObjectInstance(Object obj, Name name, Context cntx, Hashtable env)
throws NamingException{
SessionFactory sessionFactory = null;
RefAddr addr = null;
try{
Enumeration addrs = ((Reference)(obj)).getAll();
while(addrs.hasMoreElements()){
addr = (RefAddr) addrs.nextElement();
if("configuration".equals((String)(addr.getType()))){
sessionFactory = (new Configuration())
.configure((String)addr.getContent()).buildSessionFactory();
}
}
}catch(Exception ex){
throw new javax.naming.NamingException(ex.getMessage());
}
return sessionFactory;
}
}