SessionFactory and Session in hibernate

In this tutorial, we will see What is SessionFactory and Session in hibernate? How we will get Session and SessionFactory object? Also, we will see Can we create multiple SessionFactory in one application?

SessionFactory and Session in hibernate

SessionFactory In Hibernate.

SessionFactory is an interface available in org.hibernate package which extends Referenceable and Serializable interface and provides factory methods to get session object. Let’s see some points about SessionFactory.

  • SessionFactory is thread safe so multiple threads can access the SessionFactory at the same time.
  • SessionFactory is Immutable. Once we create SessionFactory we can not modify it(If you look SessionFactory methods we don’t have any setter kind of method)
  • SessionFactory is created at the time of application startup, it reads all information from the configuration file(hibernate.cfg.xml file). We will see later in details.
  • We should have one SessionFactory for one database configuration.
  • We can create a SessionFactory object using the Configuration class as below.

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

Let’s see what happens when the above line would execute.

Here first we are creating a Configuration class object and call configure() method, which has two overloaded versions. One without parameter like configure() and another one is configure(String resources). If we use configure() by default it looks for hibernate.cfg.xml file, because internally inside configure() method hibernate.cfg.xml is defined. If we use configure("hibernate.cfg.xml file") method then another overloaded version will get called. If we change our cfg file name something like hibernate.properties then we need to call other overloaded version i.e configure("hibernate.properties") method.

Let’s see how configure() method has been implemented in hibernate.

	public Configuration configure() throws HibernateException {
		configure( "/hibernate.cfg.xml" );
		return this;
	}

Observe the above code snippet. Since inside configure() method another overloaded version is getting called which loads hibernate.cfg.xml file. The only thing we need to make sure hibernate.cfg.xml file should be in the correct path.

SessionFactory and Session in hibernate

This sessionFactory object will have all the information whatever we have provided in hibernate.cfg.xml file.

Example to get SessionFactory object – 

import org.hibernate.Session;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class SessionFactoryExample{

	public static void main(String[] args) {

		SessionFactory factory = null;
		
		Configuration configuration = new Configuration().configure();

		try {

                    factory = configuration.buildSessionFactory();
		
                } catch (Exception e) {

			e.printStackTrace();

			System.out.println(e);

		} finally {

			factory.close();
		}

	}

}

Session In Hibernate.

Session is an interface available in org.hibernate package which provides different API to communicate java application to hibernate. Let’s see some points related to Session.

  • The session is not thread-safe.
  • The main use of the Session object to perform create, get, and delete operations for java classes(entity).
  • The first level cache belongs to the session object. See an example of the first-level cache in detail.
  • We can have multiple sessions for a SessionFactory.
  • We can get Session object using SessionFactory reference as below.

Session session = sessionFactory.openSession();

Example to get a Session object in Hibernate using SessionFactory.

package javatute;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class SessionExample {

	public static void main(String[] args) {
		
		SessionFactory factory = null;
		
		Session session = null;
		
		Configuration configuration = new Configuration().configure();
		
		try {
			factory = configuration.buildSessionFactory();
			
			session = factory.openSession();
			
			//session.save(entity);

			System.out.println("session object is " +session);
			
			
		} catch (Exception e) {
			
			e.printStackTrace();
			

		} finally {

			session.close();
			
			factory.close();
		}
		
	}
	
}

Can we create multiple SessionFactory in one application?

Yes, we can. But we should have two databases. There should be one SessionFactory per database. Suppose we are using two databases and we have two hibernate.cfg.xml files which contain two database configuration details.

Let’s say we have two configuration files hibernate1.cfg.xml and hibernate2.cfg.xml. The hibernate1.cfg.xml contains oracle database related configuration and hibernate2.cfg.xml contain MySQL database related configuration something like below.

hibernate1.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="connection.driver_class">oracle.jdbc.driver.OracleDriver
</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
<property name="connection.username">SYSTEM</property>
<property name="connection.password">oracle</property>
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
</session-factory> 
</hibernate-configuration>

hibernate2.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="connection.driver_class">com.mysql.jdbc.Driver
</property>
<property name="connection.url">jdbc:mysql://localhost:3306/databasename</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
</session-factory>
</hibernate-configuration>

Note – Both Configuration files(hibernate1.cfg.xml and hibernate2.cfg.xml) has been defined in same application.

Note – See more about hibernate.cfg.xml here.

We can get two SessionFactory  Using  Configuration object as below.

SessionFactory sessionFactory1 = new Configuration(“hibernate1.cfg.xml“).configure().buildSessionFactory();

SessionFactory sessionFactory2 = new Configuration(“hibernate2.cfg.xml“).configure().buildSessionFactory();

what is happening in above code? We are creating Configuration class object and calling configure() method. This configure() method loads all database details(from configuration file) and further it will return SessionFactory.

So one Database one SessionFactory another database another SessionFactory.

Now the question comes what will happen if we will try to create multiple Sessionfactory using same database configuration something like below.

SessionFactory sessionFactory1 = new Configuration(“hibernate1.cfg.xml“).configure().buildSessionFactory();

SessionFactory sessionFactory2 = new Configuration(“hibernate1.cfg.xml“).configure().buildSessionFactory();

SessionFactory sessionFactory3 = new Configuration(“hibernate1.cfg.xml“).configure().buildSessionFactory();

Did you notice we are using same database configuration file(i.e hibernate1.cfg.xml) for all three SessionFactory?

This will work fine. No exception will come. But it doesn’t make any sense. right? SessionFactory is something Util kind of thing. Create once and use throughout the application. Similar to the static method. Creating multiple SessionFactory for a single database going to impact performance, Since SessionFactory object contains the connection information, hibernate configuration information and other information.

Another related post to Session, SessionFactory, and EntityManger.

How to Get Session From EntityManager With Example.

How to get JPA EntityManager in Spring Boot.

Summary.

We can create a SessionFactory object using the Configuration class object. Once we will have a SessionFactory object then we can have a Session object. We can have multiple SessionFactory for one application.

That’s all about SessionFactory and Session in hibernate.

You may like.

SessionFcatory Docs.

Session Docs.