For test and demo purposes, we will use an embedded database that should be purged and refreshed each time we start the application. With a
Java web application, an easy way to invoke the code at startup time is by using
ServletContextListener
. We simply create a class implementing this interface, and annotate it with @WebListener
:
package com.packtpub.hibernatesearch.util; import javax.servlet.ServletContextEvent; import javax.servlet.annotation.WebListener; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; import com.packtpub.hibernatesearch.domain.App; @WebListener public class StartupDataLoader implements ServletContextListener { /** Wrapped by "openSession()" for thread-safety, and not meant to be accessed directly. */ private static SessionFactorysessionFactory; /** Thread-safe helper method for creating Hibernate sessions. */ public static synchronized Session openSession() { if(sessionFactory == null) { Configuration configuration = new Configuration(); configuration.configure(); ServiceRegistryserviceRegistry = new ServiceRegistryBuilder().applySettings( configuration.getProperties()).buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); } return sessionFactory.openSession(); } /** Code to run when the server starts up. */ public void contextInitialized(ServletContextEvent event) { // TODO: Load some test data into the database } /** Code to run when the server shuts down. */ public void contextDestroyed(ServletContextEvent event) { if(!sessionFactory.isClosed()) { sessionFactory.close(); } } }
The contextInitialized
method will now be invoked automatically when the server starts up. We will use this method to set up a Hibernate session factory, and populate the database with some test data. The contextDestroyed
method will likewise be automatically invoked when the server shuts down.
We will use this method to explicitly close our session factory when done.
Multiple places within our application will need a simple and thread-safe means for opening connections to the database (that is, Hibernate
Session
objects). So, we also add a public static synchronized
method named openSession()
. This method serves as the thread-safe gatekeeper for creating sessions from a singleton SessionFactory
.
In more complex applications, you would probably use a dependency-injection framework, such as Spring or CDI. This would be a bit distracting in our small example application, but these frameworks give you a safe mechanism for injecting SessionFactory
or Session
objects without having to code it manually.
In fleshing out the contextInitialized
method, we start by obtaining a Hibernate session and beginning a new transaction:
... Session session = openSession(); session.beginTransaction(); ... App app1 = new App("Test App One", "image.jpg", "Insert description here"); session.save(app1); // Create and persist as many other App objects as you likeā¦ session.getTransaction().commit(); session.close(); ...
Inside the transaction, we can create all the sample
data we want, by instantiating and persisting App
objects. In the interest of readability, only one object is created here. However, the downloadable source code available at http://www.packtpub.com contains a full assortment of test examples.