I am trying to configure a embedded tomcat instance in my app without any configuration files.
I have done some research and based upon this long tutorial and a shorter one i extracted this steps:
Create a
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 } }
Add that Listener to the app context
Context rootCtx = tomcat.addContext("", base.getAbsolutePath()); rootCtx.getServletContext().addListener("com.example.listeners.HibernateListener"); tomcat.start(); tomcat.getServer().await();
Implement the
HibernateUtil
class with the necessary configurationpublic 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; } }
Now i should somehow work with
MyClass
to create and retrieve data from the linked database through hibernate, right? (right now i am not sure, how exactly, but thats not the point here)
But unfortunately i am getting a NullPointerException
when im trying to add the listener to tomcat
Exception in thread "main" java.lang.NullPointerException at org.apache.catalina.core.ApplicationContext.addListener(ApplicationContext.java:1278) at org.apache.catalina.core.ApplicationContextFacade.addListener(ApplicationContextFacade.java:649)
which points to the line rootCtx.getServletContext().addListener("com.example.listeners.HibernateListener");
EDIT 1
But if i am running hibernate standalone (without tomcat) it works fine. The Data is being saved without errors!
In 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();
}
So the way i am configuring hibernate is fine i think. The error has something to do with the listener adding...
What am i doing wrong here?
I think you have missing the invocation of the method cinfigure() of the configuraton c right after your initialisation.
So it should look like this::
or
UPDATE
In order to add complete properties at runtim you can create a Prperties object and use the method.
I am not sure but using this approach it could be pssible that hibernate not looks for the hibernate.cfg.xml or .properties within classpath .
UPDATE
What you can try additionally to invoke your getConfiguration method within the getSessionFactory method instead of calling it within the static initializer of the HibernateUtil expliciteLy