Build a Hibernate SessionFactory by example

Hibernate SessionFactory tutorial

If a developer uses the Hibernate core framework, they will need to build a SessionFactory before they can do any data persistence. As the name implies, the SessionFactory produces Hibernate Sessions. Without a session, a developer can’t perform any create, update, retrieve or delete operations, which pretty much neuters the database layer.

If a developer needs to architect an enterprise offering with the Hibernate framework, these are three of the most popular approaches they can take to build a Hibernate SessionFactory:

  1. Build the Hibernate SessionFactory with a hibernate.cfg.xml file
  2. Create the SessionFactory in Hibernate with Metatada and a ServiceRegistry classes
  3. Cheat and obtain the Hibernate SessionFactory from JPA’s EntityManager

While there are other ways to build a Hibernate SessionFactory, let’s explore the three most popular options, with examples, below.

What is a SessionFactory in Hibernate?

The Hibernate SessionFactory is the most important component in the class library of JBoss’s persistence framework. The SessionFactory bootstraps the entire data persistence layer at startup as it handles important database connectivity tasks, connection pooling, thread pooling, JNDI interactions and even database table creation if persistent entities require it.

Most importantly, the SessionFactory in Hibernate is responsible for the creation of Session objects. The Hibernate Session provides methods such as save, delete and update, all of which are used to perform CRUD-based operations on the database to which the SessionFactory connects. Most applications create a Hibernate SessionFactory singleton that’s cached for the lifecycle of the app because the object is resource-intensive to create.

Hibernate is JBoss’s implementation of the JPA and most applications don’t directly interact with the Hibernate classes. The SessionFactory’s JPA companion class is the EntityManagerFactory, and it’s recommended that modern applications interact with the JPAs as much as possible. However, there are times when a Hibernate SessionFactory is required, so here are three ways to create it.

1. Build the SessionFactory with hiberante.cfg.xml

I’ve never been a big fan of XML configuration files. I much prefer the configuration to be coded within a Java source file. But the traditional and most common approach used to build the Hibernate SessionFactory is to use the hibernate.cfg.xml file.

A modern hibernate.cfg.xml file that works with Hibernate version 5.4 and uses the latest MySQL 8 drivers is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC 
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
  "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
  <hibernate-configuration>
    <session-factory>
      <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
      <!-- property name="connection.driver_class">com.mysql.jdbc.Driver</property -->
      <property name="connection.url">jdbc:mysql://localhost/hibernate_examples</property>
      <property name="connection.username">root</property>
      <property name="connection.password">password</property>
      <property name="connection.pool_size">3</property>
      <property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
      <property name="current_session_context_class">thread</property>
      <property name="show_sql">true</property>
      <property name="format_sql">true</property>
      <property name="hbm2ddl.auto">update</property>
      <!-- mapping  class="com.mcnz.jpa.examples.Player" / -->
  </session-factory>
</hibernate-configuration>

With the configuration file saved to the classpath, you can create the Hibernate SessionFactory with the following code:

public static Session getCurrentSessionFromConfig() {
  // SessionFactory in Hibernate 5 example
  Configuration config = new Configuration();
  config.configure();
  // local SessionFactory bean created
  SessionFactory sessionFactory = config.buildSessionFactory();
  Session session = sessionFactory.getCurrentSession();
  return session;
}

2. Create the Hibernate SessionFactory without XML

My personal preference is to avoid XML at all costs, which is why I always prefer to do things pragmatically. In this Hibernate SessionFactory example, you will see all of the information previously stored in XML saved to a Java HashMap and passed to a ServiceRegistry. The Hibernate ServiceRegistry is then merged with metadata about the various JPA annotated classes in the domain model. Then, we can build a Hibernate SessionFactory without a hibernate.cfg.xml file.

public static Session getCurrentSession() {
  // Hibernate 5.4 SessionFactory example without XML
  Map<String, String> settings = new HashMap<>();
  settings.put("connection.driver_class", "com.mysql.jdbc.Driver");
  settings.put("dialect", "org.hibernate.dialect.MySQL8Dialect");
  settings.put("hibernate.connection.url", 
    "jdbc:mysql://localhost/hibernate_examples");
  settings.put("hibernate.connection.username", "root");
  settings.put("hibernate.connection.password", "password");
  settings.put("hibernate.current_session_context_class", "thread");
  settings.put("hibernate.show_sql", "true");
  settings.put("hibernate.format_sql", "true");

  ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                                    .applySettings(settings).build();

  MetadataSources metadataSources = new MetadataSources(serviceRegistry);
  // metadataSources.addAnnotatedClass(Player.class);
  Metadata metadata = metadataSources.buildMetadata();

  // here we build the SessionFactory (Hibernate 5.4)
  SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build();
  Session session = sessionFactory.getCurrentSession();
  return session;
}

3. Obtain a local SessionFactory bean from JPA’s EntityManager

If a developer uses JPA, there’s a neat little trick to get the Hibernate SessionFactory from JPA’s EntityManager. First, perform a quick unwrap method call to get the Hibernate Session from the JPA EntityManager. Then call the Hibernate Session’s getSessionFactory() method. It’s a sneaky method, but it makes sense if the majority of the data persistence work uses the standard API and the developer only needs occasional access to the Hiberante SessionFactory.

public static SessionFactory getCurrentSessionFromJPA() {
  // JPA and Hibernate SessionFactory example
  EntityManagerFactory emf = 
      Persistence.createEntityManagerFactory("jpa-tutorial");
  EntityManager entityManager = emf.createEntityManager();
  // Get the Hibernate Session from the EntityManager in JPA
  Session session = entityManager.unwrap(org.hibernate.Session.class);
  SessionFactory factory = session.getSessionFactory();
  return factory;
}

Hibernate SessionFactory JPA

The SessionFactory in Hibernate can be pulled from JPA.

It’s best to stick with the standard JPAs for most software development, but it’s good to know that if a developer needs to build a Hibernate SessionFactory in their code, there are a variety of options from which to choose.

You can find the code for this Hibernate Session example that helps you update table rows and columns on GitHub.