Hibernate 配置详解(2)
6) hibernate.session_factory_name:配置一个JNDI名称,通过Configuration对象创建的SessionFactory会绑定到JNDI下该名称中。一般名字格式为jndi/someName。注意,要使用JNDI,需要在具有JNDI功能的环境之中,比如WEB容器或者EJB容器中。下面再tomcat中做一个示例,首先在一个标准的WEB项目中添加hibern
6)
配置一个JNDI名称,通过Configuration对象创建的SessionFactory会绑定到JNDI下该名称中。一般名字格式为jndi/someName。注意,要使用JNDI,需要在具有JNDI功能的环境之中,比如WEB容器或者EJB容器中。
下面再tomcat中做一个示例,首先在一个标准的WEB项目中添加hibernate的一些基本功能,接着在hibernate.properties文件中添加:
hibernate.session_factory_name
创建一个Filter作为Open
public class OpenSessioninViewFilter implements Filter {
public void destroy() {}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HibernateUtil.getInstance().getCurrentSession();
chain.doFilter(req, resp);
HibernateUtil.getInstance().closeSession();
}
public void init(FilterConfig arg0) throws ServletException {}
}
在HibernatUtil类的创建过程中就初始化并创建了一个SessionFactory,那么该SessionFactory就已经绑定在了JNDI中Naming为jndi/sf上:
private HibernateUtil() {
sf = new Configuration().configure().buildSessionFactory(
new ServiceRegistryBuilder().buildServiceRegistry());
}
接着再创建一个Filter来验证JNDI是否绑定成功:
public class SomeFilter implements Filter {
public void destroy() {}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
try {
Context ctx = new InitialContext();
System.out.println(ctx.lookup("jndi/sf"));
} catch (Exception e) {
e.printStackTrace();
}
chain.doFilter(req, resp);
}
public void init(FilterConfig arg0) throws ServletException {}
}
该Filter仅仅是很简单的从上下文中找到名字为jndi/sf的资源并打印出来。要能够正常打印,必须要保证open <filter>
<filter-name>osiv</filter-name>
<filter-class>util.OpenSessioninViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>osiv</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>filter</filter-name>
<filter-class>util.SomeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
运行应用,随意请求一个地址,后台打印:
org.hibernate.internal.SessionFactoryImpl@6186ee4d
已经工作正常。注意一点的就是,如果只是在JUnit中测试Hibernate,在Hibernate启动过程当中就会看到这样的异常:
WARN: HHH000277: Could not bind factory to JNDI
org.hibernate.service.jndi.JndiException: Error parsing JNDI name [foo]
at org.hibernate.service.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:92)
at org.hibernate.service.jndi.internal.JndiServiceImpl.bind(JndiServiceImpl.java:108)
at org.hibernate.internal.SessionFactoryRegistry.addSessionFactory(SessionFactoryRegistry.java:89)
at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:480)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1750)
at cd.itcast.hibernate.day1.jdbc.HibernateUtil.(HibernateUtil.java:15)
at cd.itcast.hibernate.day1.jdbc.HibernateUtil.(HibernateUtil.java:10)
at cd.itcast.hibernate.day1.jdbc.UserTest.test(UserTest.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getNameParser(Unknown Source)
at org.hibernate.service.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:86)
... 30 more
该异常并不影响Hibernate的正常使用,其原因是因为在hibernate的project/etc/中的hibernate.cfg.xml文件模板中,sessionFactory配置了name这个属性,这个属性同hibernate.session_factory_name作用相同,也是用于指定JNDI绑定名称,因为在JUNIT环境下没有JNDI功能,所以绑定失败,报错。要去掉这个异常,只需要把SessionFactory元素的name属性删除即可。
更多推荐
所有评论(0)