Hibernate Core concepts overview
We need to understand the below concepts in Hibernate before using them in coding
Configuration
SessionFactory
Session
Let’s see them in detail
Configuration
Hibernate should have the information to map the java classes with the database tables.
This information is ideally kept in the mapping XML file.
Hibernate also need to have the database related configuration like database url, credentials , dialect etc.
This information to find out the mapping files and the database configuration is provided in the hibernate configuration file.
The default names for this configuration file will be either hibernate.properties or hibernate.cfg.xml
We can use any other name as well for the configuration.
org.hibernate.cfg.Configuration is used to build an instance of immutable org.hibernate.SessionFactory
We will see about SessionFactory and its immutability soon.
Configuration will be created as below with default configuration file
- Configuration cfg=new Configuration();
- cfg=cfg.configure();
Configuration cfg=new Configuration(); cfg=cfg.configure();
whenever we call configure() method It looks for hibernate cfg.xml and also looks for hibernate mapping file.
Configuration will be created as below with custom configuration file
- Configuration cfg=new Configuration();
- Configuration cfg1=cfg.configure(“application.cfg.xml”);
Configuration cfg=new Configuration(); Configuration cfg1=cfg.configure(“application.cfg.xml”);
Here we are passing custom file name to configure() method and hence it looks for application.cfg.xml and also looks for hibernate mapping file.
Session Factory
SessionFactory is the factory for the session objects.
We use Configuration object to build the SessionFactory, It will be only one per database but there can be multiple session objects
We obtain SessionFactory using Configuration object as below
- SessionFactory sessions = cfg.buildSessionFactory();
SessionFactory sessions = cfg.buildSessionFactory();
If we have multiple databases in our application, then we need to create multiple SessionFactory objects
Example:
If we are using 2 databases called mysql and oracle in our application then we need to build 2 SessionFactory objects as below
- Configuration cfg=new Configuration();
- Configuration cfg1=cfg.configure(“mysql.cfg.xml”);
- SessionFactory sf1=cfg1.buildSessionFactory();
- Configuration cfg2=cfg.configure(“oracle.cfg.xml”);
- SessionFactory sf2=cfg2.buildSessionFactory();
Configuration cfg=new Configuration(); Configuration cfg1=cfg.configure(“mysql.cfg.xml”); SessionFactory sf1=cfg1.buildSessionFactory(); Configuration cfg2=cfg.configure(“oracle.cfg.xml”); SessionFactory sf2=cfg2.buildSessionFactory();
Now sf1 is associated with mysql and sf2 is associated with Oracle database.
Why SessionFactory is immutable and thread safe ?
In Real time, many threads can access the SessionFactory concurrently to request a session, If the object is mutable , then accessing such mutable objects by multiple threads concurrently can lead to inconsistent state.
Hence making such object as immutable will always be thread safe.
Session
Session acts as a main bridge between Java application and Hibernate
We can establish a connection with database and interact with it using Session.
Session is a lightweight object and hence can be created whenever the interaction with Database is necessary.
Unlike SessionFactory, Session is not thread safe and hence it should not be kept open for a long time.
So Create and close the session on a need basis.
Each Session is bounded by the beginning and end of a logical transaction.
We can use the session as below
- Session session = sessionFactory.openSession();
- Transaction tx;
- try {
- tx = session.beginTransaction();
- //do DB related work
- ...
- tx.commit();
- }
- catch (Exception e) {
- if (tx!=null) tx.rollback();
- throw e;
- }
- finally {
- session.close();
- }
Session session = sessionFactory.openSession(); Transaction tx; try { tx = session.beginTransaction(); //do DB related work ... tx.commit(); } catch (Exception e) { if (tx!=null) tx.rollback(); throw e; } finally { session.close(); }
sessionFactory.openSession() is used to obtain the session from SessionFactory
session.beginTransaction() is used to begin the transaction
tx.commit() is used to commit the transaction
tx.rollback() is used to roll back the transaction if any exception is thrown
session.close() is used to close the session.
It is good practice to Rollback the entire transaction whenever any exception is thrown within the session as shown in the Catch block.
The internal state of the Session might not be consistent with the database after the exception is thrown and hence we should discard the session hence closing it in the finally block.