Sunday, June 22, 2014

Hibernate Object Relational Mapping

Continuing from the post on Object Relational Mapping let us look at Hibernate Object Relational mapping implementation.


Hibernate ORM is an Object Relational Mapping framework for persisting Java objects to a Relational Database System. Hibernate provides a native API (SessionFactory, Criteria API and Hibernate configuration files), and also fully implements JPA (Java Persistent API) specifications which is the more preferred way on integrating with Hibernate ORM framework.   

General architecture of Hibernate is depicted in the following diagram:


SessionFactory : Contains Thread safe cache of compiled object relational mappings for a single database.

Session: Single threaded short lived object that is used by applications to access persistent store.  

Persistent Objects: Single threaded Short-lived objects containing persistent state and business function which are a associated with exactly one Session. 

Transaction : Single threaded, short-lived object specifying atomic units of work.

TransactionFactory: A factory for creating Transaction instances, this is used indirectly by application for managing transactions

Application creates persistent objects, these objects may be annotated using JPA entity annotations or may be POJO (Plain Old Java Objects) with explicit hibernate mapping xml files. Application then obtains SessionFactory to perform CRUD based operations on the relational database using hibernate Session. 

Please refer to Hibernate documentation for more details.


Hibernate Tools Project

Hibernate tools project is a good way to get started in generating base components and pojo mappings for relational database entity model. Hibernate tools can be easily integrated into eclipse via eclipse market place.  

One of feature of hibernate tools is its reverse engineering capabilities to generate domain model classes, mapping files, annotated entity beans very quickly to get started with Hibernate ORM, it reads database constructs and generates basic CRUD entities, however it may generate more stuff than you want or may not generate entity fields that you would expect. 

Hibernate tools does provide a mechanism for specifying table entries and columns via the reveng.xml mapping file where one can control basic features, however for more complex mapping strategies one would have to extend org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy and implement custom reverse engineering strategy. 

Further more with respect to annotations, the reverse engineered entity model will contain method level annotations on getter methods and no field level annotations, personally I feel having field level annotations is much cleaner, but to have field level annotations one must again write custom templates, all on this seems like an overkill, I would stick to annotating POJO fields manually. 

More details on Hibernate Tools and Reverse Engineering can be found at here

The feature that I like most about Hibernate Tools is the Hibernate Console Configuration, which can be quickly used to validate  and execute HQL (Hibernate Query Language) / JPQL (Java Persistent API Query Language) queries and generate mapping diagrams showing a visual representation of the Object Relational Mapping model which works well for small concise model but may be a little too overwhelming for large models. 

Hibernate Implementation:

Please refer to previous post if you plan to import the test project onto local machine and run code locally. 

Annotated Model Object: 
The com.malcolm.daotest.hibernate.model package contains JPA annotated model, which is pretty straight forward. We annotate each Java object with the @Entity,  @Table and @Column annotation at minimum. JPA annotations are found in the javax.persistence.* package.  Please refer here for declaring Object Relational Mapping in the POJO beans. 


Hibernate DAO Implementation: 
The com.malcolm.daotest.hibernate.dao.hibernateimpl.EmployeeDAOHibernateImpl class provides a native hibernate implementation via the Hibernate SessionFactory and Criteria API, I should say its more like semi native, since we are not using Hibernate Mapping Files (*.hbm.xml) containing POJO Relational Database System mapping but rather using JPA annotated beans.

The EmployeeDAOHibernateImpl has autowired SessionFactory and @Repository annotation marking it as a DAO class for encapsulating storage, retrieval, and search behavior.


Hibernate Configuration:

The com.malcolm.daotest.hibernate.HibernateDAOConfig sets up the required bean dependency setting the SessionFactory and TransactionManager, the datasource and hibernate properties are configured in the BaseHibernateDAOConfig.


Hibernate JPA DAO Implementation: 

Using JPA is the preferred way of integrating Object Relational Mapping with Hibernate which fully implements JPA2.1 in Hibernate 4.3.5.
The com.malcolm.daotest.hibernate.dao.hibernateimpl.EmployeeDAOHibernateJPAImpl class provides JPA implementation via the EntityManager, Join Fetch strategy is used to avoid the hibernate N+1 problem.


Note: Even though we have specified a JOIN FETCH strategy to eliminate n+1 issue with multiple calls to the database, we will still have a issue if there are multiple collection based relationships and n+1 issue will occur, if we try to put a JOIN FETCH strategy for all collections we will get a Cartesian product. The only way to control such an issue is to use appropriate LAZY and EAGER load strategy of collection objects.

In the test project the Employee entity object has two relation based collections, employee roles and employee project associations, I was not successful to eliminate the n+1 issue for getting employee roles.

Hibernate JPA Configuration:

The com.malcolm.daotest.hibernate.HibernateDAOJPAConfig sets up the required bean dependency setting the EntityManager and TransactionManager, the datasource and hibernate properties are configured in the BaseHibernateDAOConfig.

The DAO uses the @ComponentScan annotations to clearly mark the DAO and Service Components





Hibernate Implementation Design:


Hibernate Tools Console Configuration:

As mentioned earlier, the Hibernate tools eclipse plugin is very useful to quick check HQL/JPQL queries. First set up Hibernate Console Configuration by providing, project, database connection and hibernate configuration file.


Opening the HQL Editor quickly allows to validate HQL queries.



Strengths:
  1. No JDBC boiler plate code. 
  2. Supports paginations, connection pooling and caching mechanisms.  
  3. Hibernate uses dialect classes for underlying databases so can work across multiple databases. selecting the right.
  4. Hibernate easily supports relationships like One-to-One, Many-to-One, Many-to-Many.
  5. Support Lazy and Eager strategies for loading relationship
  6. Hibernate can generate primary keys with different generation strategies;
  7. Fully supports JPA implementation.
Weakness:
  1. Can encounter N+1 issues where multiple SQL queries are fired to fetch relational data elements.
  2. Appropriate Lazy and Eager strategies must be evaluated to avoid n+1 issues.
  3. Fetch Join strategies must be evaluated carefully for cartesian products.
  4. Need to be proficient with HQL (Hibernate Query Language) / JPQL (JPA Query Language).
  5. No much control in fine tuning queries generated with Hibernate at runtime, may be forced to use Native Queries to address performance issues. 
Please refer to Hibernate Reference for further details.  

Back to previous post on Object Relational Mapping.

Until next time,
Malcolm

Back to Java Thoughts

No comments:

Post a Comment