我正在尝试在没有任何配置文件的应用程序中配置嵌入式tomcat实例。
我做了一些研究,基于这个long tutorial和a shorter one我提取了这个步骤:
创建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
}
}
将该监听器添加到应用程序上下文
Context rootCtx = tomcat.addContext("", base.getAbsolutePath());
rootCtx.getServletContext().addListener("com.example.listeners.HibernateListener");
tomcat.start();
tomcat.getServer().await();
使用必要的配置实现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;
}
}
现在我应该以某种方式使用MyClass
通过hibernate从链接数据库创建和检索数据,对吧? (现在我不确定,究竟是什么,但这不是重点)
但不幸的是,当我试图将监听器添加到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的方式很好。该错误与侦听器添加...
有关我在这里做错了什么?
答案 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;
}