Hibernate, hibernate-jpa, Spring ORM, Spring data JPA and many more. All this seems to be confusing but they all are just jars which are automatically added when you add the below line you pom.xml.
Basically, Spring boot gives a starter project for your data access layer which is based on ORM concept and by default usage hibernate as persistent api. This blog we are not going to discuss about how spring encapsulated hibernate under it but we are going to discuss about Hibernate basics and there Spring alternative way of writing code.
Hibernate in action with JPA.
- Create Entity class
- Create Repository interface
- Use repository.
Pros and Cons of Hibernate over Plain JDBC.
Hibernate is a ORM Object-relational mapping, It maps the entity classes to database tables. Sometime it easy to map one to one entity to table but sometime it really gets complex when you have inheritance, different kind of table relationships such as one to one, one to many and many to many. Also it really gets messy if you don’t handle the fetch and cascade parameters properly. But over all it has many advantages over its disadvantages. That why it is so popular.
- Reduces and reusage code.
You don’t need write query again and again for insert update or anything.
- Independent of database.
You can use any underlying database without modifying your code. You just need change dialect and pom entry to update driver of the database.
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.DB2Dialect
- Lazy loading.
Hibernate you can set the property to lazy load the related table data and hibernate takes care of fetching the data when the data is required.
- Transaction management.
Hibernate maintains the transaction and revert all the changes in case if there is any exception.
In memory is always faster then the reaching out to DB for the data. Hibernate has inmemory caching option it keeps data in memory which is faster to access and is very smart when to commit and when not to.
- Connection Pooling.
Inbuilt support of connection pooling. It create pool of connection which is faster then creating a new connection and terminating it.
- Supports HQL(superset of JPQL).
HQL is a query language supported in Hibernates, In queries you can directly use classname and it automatically generates the database queries.
- Automatic versioning.
Maintains different version of data and saves the headach of missing the data.
The query generated here will be highly optimized in most of the cases.
Setting up Datasource.
If you start with starter-jpa datasource and started inmemory DB jar such as h2database etc, you don’t need to define the datasource but you can define and override the default ones. Here is Java way of defining it.
Here is defining the datasource by just property files. Make sure you use exact keys.
Object States in Hibernate
Object just created but not attached to hibernate session and not connected to database.
Object attached hibernate session and connected to database, any update to this will be reflected in database.
Object detached from session. It happened when session is closed or you can manually detach it.
Session, SessionFactory and Transaction.
SessionFactory provide you the session class which can be used to attach, detach, save, query etc. Session supports transaction as well.
Annotations used class table mapping.
@Entity - Makes the class available for Table mapping.
@Table - It is optional. Used with @Entity, in case you want different name of the table.
@Column - It is optional, in case you want different name of the field.
@Id - Makes field primary key, you will have to use @GeneratedValue if you want generated values of id.
@GeneratedValue - To generate field value. There four type of it. Auto(Unique value across database), identity(Unique across class hierarchy), sequence(custom sequence ex:start:100, increment- 10), Table.
@Version - For versioning and concurrency you can keep a field which defines a version.
@Transient - In case you don’t want a field to be part of database mapping.
@OnetoOne - When there is one to one relation, but again it has four different types.
@PrimaryKeyJoinColumn - When two table share same primary key. Such as Employee and EmployeeDetails.
@MapsId - When tables joined by foreign and primary key of two tables and both class cotains object of each other. Such Employee and EmployeeBadge.
@OneToMany & @ManyToOne - Both are represent same logical thing. A Project can have many employees which is one to many. Many employee can be mapped a single project which is many to one. It depends how you organize your java class.
@ManyToMany - Many to many relation always needs a third table. For example employee can work on many tasks and a task can have multiple employees working on it.
Hibernates provides many way to query you table. Native, HQL, criteria etc. HQL is extension of SQL almost same as SQL standards but it usage class name in place of table name. Also, binging a value is very easy. You can retrieve query object from session and Query interface has following methods.
- public int executeUpdate()
- public List list()
- public Query setFirstResult(int rowno) //For pagination set the first row num
- public Query setMaxResult(int rowno) // Page count
- public Query setParameter(int position, Object value)
- public Query setParameter(String name, Object value)
Criteria api helps you to omit sqls or HQL where you have to pass the query as string. Criteria API provides you set of classes and utilities with which you can form queries. You can create Criteria object form session.
Criteria ct = session.createCriteria(Employee.class);
Using Restriction - Restriction class with and, or, eq, ne, gt, lt, ge, le, like,ilike, between, in, conjunction, disjunction, isNull, isNotNull, sqlRestriction(String sql, Object value, Type type) etc.
Using Projection to get selecte Columns
- avg(String propertyName)
- count(String propertyName)
- countDistinct(String propertyName
- max(String propertyName)
- min(String propertyName)
- sum(String propertyName)
Using query by example Query by example usage a filter object. Let’s say you want filter a employee based on salary and age. Create a filter object with salary and age set.
Caching in Hibernate.
Hibernates has two level level of cache. First level is by default there and maintained by session container. You can’t change first level cache. Second level cache is left for developer where he can defined his own caching strategies at each class level. Such as Employee class secondary cache can use any of the below strategies.
Transactional - Cached data will be retained only in transaction.
Read-write - It create read write lock on table and updates if the data has been updated.
Nonstrict-read-write - When data rarely changes and you don’t bother about stale data. Read-only - When data never changes.