zoukankan      html  css  js  c++  java
  • Hibernate 配置详解(2)

    6) hibernate.session_factory_name

    配置一个JNDI名称,通过Configuration对象创建的SessionFactory会绑定到JNDI下该名称中。一般名字格式为jndi/someName。注意,要使用JNDI,需要在具有JNDI功能的环境之中,比如WEB容器或者EJB容器中。

    下面再tomcat中做一个示例,首先在一个标准的WEB项目中添加hibernate的一些基本功能,接着在hibernate.properties文件中添加:


    hibernate.session_factory_name jndi/sf


    创建一个Filter作为Open Session In View过滤器:

    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就已经绑定在了JNDINamingjndi/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 session in view 过滤器在该SomeFilter之前运行(主要的目的是要求在第一次使用JNDI查找SessionFactory资源之前完成SessionFactory的实例化):
    <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的正常使用,其原因是因为在hibernateproject/etc/中的hibernate.cfg.xml文件模板中,sessionFactory配置了name这个属性,这个属性同hibernate.session_factory_name作用相同,也是用于指定JNDI绑定名称,因为在JUNIT环境下没有JNDI功能,所以绑定失败,报错。要去掉这个异常,只需要把SessionFactory元素的name属性删除即可。

  • 相关阅读:
    广佛肇城轨年内通车 佛山西站预计2017年中通车
    MTK+Android编译
    电量检测芯片BQ27510使用心得
    放大电路的分析方法
    放大电路的分析方法
    模拟电子放大电路分析
    模拟电子技术二极管
    unsigned 整型实现无溢出运算
    hdu 5317 RGCDQ(前缀和)
    CodeForces 429 B Working out(递推dp)
  • 原文地址:https://www.cnblogs.com/james1207/p/3275414.html
Copyright © 2011-2022 走看看