How to build Hibernate SessionFactory

SessionFactory is an interface from the org.hibernate package. SessionFactory can be created by providing the Configuration object, the main objective of sessionFactory is to the creation of Session instances.

Usually, an application has a single SessionFactory instance and threads servicing client requests obtain Session instances from this factory.

This is due to the session factory is a heavy object and for creation, it consumes more resources. Once the session factory object is created, its internal state is set which includes all of the metadata about Object/Relational Mapping. It is threadsafe.

We can create one SessionFactory implementation per database in any application. If your application is referring to multiple databases, then you need to create one SessionFactory per database.

In this tutorial, we will see how to create a session factory, and later we will see various useful methods from the SessionFactory class.

1). XML based configuration.

In this approach, we need to specify a full configuration in a file named hibernate.cfg.xml. This file can be used as a replacement for the hibernate.properties file or, if both are present, to override properties.

The XML configuration file is by default expected to be in the root of your CLASSPATH

Maven dependencies

<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.4.20.Final</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.200</version> </dependency>

hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">org.h2.Driver</property> <property name="hibernate.connection.url">jdbc:h2:mem:test</property> <property name="hibernate.connection.username">sa</property> <property name="hibernate.connection.password"></property> <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create-drop</property> <mapping class="com.javacodestuffs.hibernate.entity.Student"></mapping> <property name="hibernate.current_session_context_class">thread</property> </session-factory> </hibernate-configuration>

We can put this file in the classpath or in any other location, but if you put it to another location, you have to load it as a file object.

File f = new File("D:\\hibernate\\hibernate.cfg.xml"); SessionFactory sessionFactory = new Configuration().configure(f).buildSessionFactory();

this approach, the advantage is, in case of web applications, if you have no access to the war file but can get access to the hibernate file in a different directory, say for maintenance.

String hibernatePropsFilePath = "/etc/configs/hibernate.cfg.xml"; File hibernatePropsFile = new File(hibernatePropsFilePath); Configuration configuration = new Configuration(); configuration.configure(hibernatePropsFile); StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()); ServiceRegistry serviceRegistry = serviceRegistryBuilder.build(); SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);

package com.javacodestuffs.hibernate.util; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; public class HibernateUtil1 { private static SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { if (sessionFactory == null) { StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder() .configure("hibernate.cfg.xml").build(); Metadata metaData = new MetadataSources(standardRegistry) .getMetadataBuilder() .build(); sessionFactory = metaData.getSessionFactoryBuilder().build(); } return sessionFactory; } catch (Exception ex) { System.out.println("Execption occured during session factory creation"+ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { getSessionFactory().close(); } }

OR

package com.javacodestuffs.hibernate.util; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; public class HibernateUtil2 { private static SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { if (sessionFactory == null) { SessionFactory sf = new Configuration().configure().buildSessionFactory(); You can select a different XML configuration file using: SessionFactory sf = new Configuration() .configure("hibernate.cfg.xml") .buildSessionFactory(); } return sessionFactory; } catch (Exception ex) { System.out.println("Execption occured during session factory creation"+ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { getSessionFactory().close(); } }

Student.java

package com.javacodestuffs.hibernate.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.UniqueConstraint; @Entity @Table(name = "Student", uniqueConstraints = { @UniqueConstraint(columnNames = "roll_number"), @UniqueConstraint(columnNames = "phone") }) public class Student implements Serializable { private static final long serialVersionUID = -1798070786993154676L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "roll_number", unique = true, nullable = false) private Integer rollNumber; @Column(name = "first_name", unique = false, nullable = false, length = 100) private String firstName; @Column(name = "last_name", unique = false, nullable = false, length = 100) private String lastName; @Column(name = "phone", unique = true, nullable = false, length = 100) private String phone; @Column(name = "student_class", unique = true, nullable = false, length = 100) private String studClass; //@Getters //@Setters }

To run the application we have the main class

import org.hibernate.Session; import com.javacodestuffs.hibernate.entity.Student; public class SeesionFactoryTest { public static void main(String[] args) { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); //Add new Student object Student student = new Student(); student.setPhone("1234567890"); student.setStudClass("9th"); student.setAddress("Flat no 312,Chandani Chowk Pune - 411038"); student.setFirstName("Bala"); student.setLastName("K"); session.save(student); session.getTransaction().commit(); HibernateUtil.shutdown(); } }

2). Annotation-based configuration.

An instance of org.hibernate.cfg.Configuration represents an entire set of mappings of an application's Java types to an SQL database. The org.hibernate.cfg.Configuration is used to build an immutable org.hibernate.SessionFactory.

We can also load Student.hbm.xml files also. Please see the tutorial for hbm.xml files.

You can obtain an org.hibernate.cfg.Configuration instance by instantiating it directly and specifying XML mapping documents. If the mapping files are in the classpath, use addResource(). For example:

Configuration cfg = new Configuration() .addResource("Student.hbm.xml") .addResource("Subjects.hbm.xml");

An alternative way is to specify the mapped class and allow Hibernate to find the mapping document for you:

Configuration cfg = new Configuration() .addClass(org.hibernate.auction.Student.class) .addClass(org.hibernate.auction.Subjects.class)

Hibernate will then search for mapping files named /org/hibernate/auction/Student.hbm.xml and /org/hibernate/auction/Subjects.hbm.xml in the classpath. This approach eliminates any hardcoded filenames.

The hibernate.cfg.Configuration also allows you to specify configuration properties. For example:

Configuration cfg = new Configuration() .addClass(com.javacodestuffs.hibernate.entity.Student.class) .addClass(com.javacodestuffs.hibernate.entity.Subjects.class) .setProperty("hibernate.dialect", "org.h2.Driver") .setProperty("hibernate.connection.datasource", "dbc:h2:mem:test") .setProperty("hibernate.order_updates", "true") .setProperty("hibernate.connection.username","sa") .setProperty("hibernate.connection.password","") .setProperty("hibernate.dialect","org.hibernate.dialect.H2Dialect") .setProperty("show_sql","true") .setProperty("hbm2ddl.auto","create-drop") .setProperty("hibernate.current_session_context_class","thread");

sample hibernate.properties file:

hibernate.connection.driver_class =org.h2.Driver hibernate.connection.url =jdbc:h2:mem:test hibernate.connection.username =sa hibernate.connection.password = hibernate.dialect =org.hibernate.dialect.H2Dialect show_sql =true hbm2ddl.auto =create-drop hibernate.current_session_context_class =thread hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.timeout=1800 hibernate.c3p0.max_statements=50 hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

Hibernate JDBC Properties and descriptions

hibernate.connection.driver_class JDBC driver class hibernate.connection.url JDBC URL hibernate.connection.username database user hibernate.connection.password database user password hibernate.connection.pool_size maximum number of pooled connections

SessionFacory using annotations

package com.javacodestuffs.hibernate.app; import com.javacodestuffs.hibernate.entity.Student; import java.util.Properties; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.service.ServiceRegistry; public class HibernateUtilAnnotationBase1 { private static SessionFactory sessionFactory; public static SessionFactory getSessionFactory() { if (sessionFactory == null) { try { Configuration configuration = new Configuration(); // Hibernate settings no need to load hibernate.cfg.xml file Properties settings = new Properties(); settings.put(Environment.DRIVER, "org.h2.Driverr"); settings.put(Environment.URL, "jdbc:h2:mem:test"); settings.put(Environment.USER, "sa"); settings.put(Environment.PASS, ""); settings.put(Environment.DIALECT, "org.hibernate.dialect.H2Dialect"); settings.put(Environment.SHOW_SQL, "true"); settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread"); settings.put(Environment.HBM2DDL_AUTO, "create-drop"); configuration.setProperties(settings); configuration.addAnnotatedClass(Student.class); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()).build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); } catch (Exception ex) { System.out.println("Execption occured during session factory creation"+ex); } } return sessionFactory; } }

In this article, we have seen How to build Hibernate SessionFactory with examples. All source code in the article can be found in the GitHub repository.