以编程方式配置嵌入式tomcat 7的hibernate

时间:2014-01-01 20:31:00

标签: java hibernate tomcat hsqldb embedded-tomcat-7

我正在尝试在没有任何配置文件的应用程序中配置嵌入式tomcat实例。

我做了一些研究,基于这个long tutoriala shorter one我提取了这个步骤:

  1. 创建ServletContextListener

    @WebListener //some articles on the web mentioned, that this would add the 
    //Listener automatically to the app context, but i cant believe that this works in my case
    public class HibernateListener implements ServletContextListener {
    
        public void contextInitialized(ServletContextEvent event) {
            HibernateUtil.getSessionFactory(); // create a factory
        }
    
        public void contextDestroyed(ServletContextEvent event) {
            HibernateUtil.getSessionFactory().close(); // free resources
        }
    }
    
  2. 将该监听器添加到应用程序上下文

    Context rootCtx = tomcat.addContext("", base.getAbsolutePath());
    rootCtx.getServletContext().addListener("com.example.listeners.HibernateListener");
    
    tomcat.start();
    tomcat.getServer().await();
    
  3. 使用必要的配置实现HibernateUtil

    public class HibernateUtil {
    
        private static final SessionFactory sessionFactory;
    
        static {
            try {
                //should i call .configure() on the returned Configuration here?                
                sessionFactory = getConfiguration()
                        .buildSessionFactory();
            } catch (Throwable ex) {
                System.err.println("Initial SessionFactory creation failed." + ex);
                throw new ExceptionInInitializerError(ex);
            }
    
        }
    
        private static Configuration getConfiguration(){
            Configuration c = new Configuration();
    
            c.setProperty("hibernate.connection.url", "jdbc:hsqldb:hsql://localhost:1234/mydb1");
            c.setProperty("hibernate.connection.username", "SA");
            c.setProperty("hibernate.connection.password", "");
            c.setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver");
    
    
            c.setProperty("dialect", "org.hibernate.dialect.HSQLDialect");
            c.setProperty("cache.provider_class", "org.hibernate.cache.NoCacheProvider");
            c.setProperty("cache.use_query_cache", "false");
            c.setProperty("cache.use_minimal_puts", "false");
            c.setProperty("max_fetch_depth", "3");
    
            c.setProperty("show_sql", "true");
            c.setProperty("format_sql", "true");
            c.setProperty("hbm2ddl.auto", "create");
    
            c.addPackage("com.example.models");
            c.addAnnotatedClass(MyClass.class);
    
            return c;
        }
    
        public static SessionFactory getSessionFactory() {
            return sessionFactory;
        }
    }
    
  4. 现在我应该以某种方式使用MyClass通过hibernate从链接数据库创建和检索数据,对吧? (现在我不确定,究竟是什么,但这不是重点)

  5. 但不幸的是,当我试图将监听器添加到tomcat时,我得到NullPointerException

      

    线程“main”中的异常java.lang.NullPointerException at   org.apache.catalina.core.ApplicationContext.addListener(ApplicationContext.java:1278)     在   org.apache.catalina.core.ApplicationContextFacade.addListener(ApplicationContextFacade.java:649)

    指向第rootCtx.getServletContext().addListener("com.example.listeners.HibernateListener");

    编辑1

    但如果我正在运行 hibernate standalone (没有tomcat),它可以正常。保存数据没有错误!

    HibernateUtil

    public static void main(String[] args) {
        MyClass mycls = new MyClass();
    
        mycls.setMyProperty("My Property");
        Session session = getSessionFactory().openSession();
        Transaction transaction = session.beginTransaction();
        session.save(mycls);
        transaction.commit();
    }
    

    所以我认为我配置hibernate的方式很好。该错误与侦听器添加...

    有关

    我在这里做错了什么?

2 个答案:

答案 0 :(得分:4)

深入挖掘Tomcat的源代码后,我找到了一个可能的解决方案:

rootCtx.addApplicationListener(new ApplicationListener("com.example.listeners.HibernateListener", false));

它做我需要的!

答案 1 :(得分:0)

我认为你错过了configuraton c的方法cinfigure()的调用 在你初始化之后。

所以看起来应该是这样的::

 SessionFactory sessionFactory =  getConfiguration().confgure().buildSessionFactory();

c = getConfiguration();
sessionFactory = c.configure().buildSessionFactory();

更新

为了在runtim添加完整属性,您可以创建一个Prperties对象并使用该方法。

  configuration.buildSettings(Properties props)

我不确定但是使用这种方法可能是因为hibernate没有在类路径中查找hibernate.cfg.xml或.properties。

更新

你还可以尝试在getSessionFactory方法中调用你的getConfiguration方法,而不是在HibernateUtil expliciteLy的静态初始化器中调用它

public static getSessionFactory() {
    Configuration c = getConfiguration();
    sessionFactory = c.buildSessionFactory();
    return sessionFactory;
}