# Hibernate

* A Complete solution to the problem of managing persistence in Java.
* An ORM tool _(Object Relational Mapping)_ used mainly in data access layer or DAO layer.
* JPA _(Java Persistence API)_ specification implementor and is an object oriented abstraction.
* It is an automatic & transparent persistence framework to store & retrieve data from database.
* Open Source Java based framework founded by Gavin King in 2001, which was hosted on [hibernate.org](https://hibernate.org/). Currently hosted on [sourceforge.net](https://sourceforge.net/projects/hibernate/).
* Java Persistence API _(JPA)_ compliant current version of hibernate is `Hibernate 5.x`, and latest release is `6.x`.
* Other popular ORM Frameworks are EclipseLink, iBATIS, Kodo etc. ![hibernate diagram](https://574639531-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJDnjsv52I3fJ56WbLgHu%2Fuploads%2Fgit-blob-fb1ac3c2d4075719ceebf5a2c91f2fc12efe9d69%2Fhibernate_overview.png?alt=media)

## JPA and Hibernate

* JPA is a standard part of J2EE specification whose vendor is J2EE _(sun)_.
* Implementation classes of these specification is hibernate-core JARs _(implementor of JPA)_.

## Why Hibernate?

![hibernate and Java](https://574639531-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJDnjsv52I3fJ56WbLgHu%2Fuploads%2Fgit-blob-737f5172ab7480e926f44c510b25d054612ef388%2Fhibernate_overview_2.png?alt=media)

* It mediates the applications interaction with a relational database, so that the developer can concentrate on the business problem at hand.
* J2EE developer does not have to use JDBC API & manage data persistence at RDBMS level.
* No need to go to Table/Query/Column level.
* One has to bootstrap Hibernate framework, create transient i.e., not yet persistent POJOs & then rely entirely on Hibernate framework to manage persistence.

[why choose hibernate](https://github.com/jojijoy15/Notes/blob/main/Languages/Java/01_Backend/06_ORM_Hibernate/readmes/why_hibernate.md)

## More about Hibernate

* There is huge mismatch between Object & Relational Database world, formally referred as `Object-Relational Impedance Mismatch` _(sometimes called the `paradigm mismatch`)_
* Important Mismatch Points
  1. Granularity
  2. Sub Types or inheritance and polymorphism
  3. Identity
  4. Associations
  5. Data Navigation
* Cost of Mismatch
  1. SQL queries in Java code
  2. Iterating through ResultSet & mapping it to POJOs or entities.
  3. SQLException handling.
  4. Transaction management
  5. Caching
  6. Connection pooling
  7. Boiler plate code
* Hibernate `4.x` and above is a JPA compliant Java persistence API which is a part of J2EE specifications.
* It is fully JPA compliant, however it also has additional services/annotations specific to Hibernate.
* Developer **MUST add** hibernate JARs while deploying application on web server.
* Developer need not add JPA provider JARs, while working on application server.
* Transparent persistence provider. _(As POJOs or Entities are not bound to any Persistence API, its written completely independent of Persistence Provider.)_
* Fully supports OOP features such as association, inheritance & polymorphism
* It can persist object graphs, consisting of associative objects.
* Caches data which is fetched repeatedly _(via L1 & L2 cache)_ and thus reducing DB traffic.
  * L1 cache, sits at session level which is a built in.
  * L2 cache which is pluggable, sits at global session factory level._(More on caching at the end)_.
* Supports lazy loading and thus increases DB performance.
  * Lazy fetching
    * The associated object or collection is fetched lazily, when its first accessed.
    * This results in a new request to the database _(unless the associated object is cached)_.
  * Eager fetching
    * The associated object or collection is fetched together with the owning object, using an SQL outer join, and no further database request is required.
* Supports objectified version of SQL i., `HQL` works on objects & properties.
* Hibernate usually obtains exactly the right lock level automatically. Hence, developer need not worry about applying Read/Write lock.

## Working of hibernate

1. Hibernate uses runtime reflection to determine the persistent properties of a class.
2. The objects to be persisted _(called as POJO or Entity)_ are defined in a mapping document or marked with annotations. Either these `HBM XML` _(hibernate mapping)_ configuration or annotations serves to describe the persistent fields and associations, as well as any subclasses or proxies of the persistent object.
3. The mapping documents or annotations are compiled at application startup time and provide the framework with necessary information for a persistent class.
4. What is Hibernate configuration?
   * An instance of Hibernate configuration allows the application to specify properties and mapping documents to be used at the framework start-up.
   * The configuration is an initialization-time object.
5. `SessionFactory` is created from the compiled collection of mapping documents. The `SessionFactory` provides the mechanism for managing persistent classes through the `Session` interface.
6. A web application or Java SE application will create a single configuration, build a single instance of SessionFactory and then instantiate multiple session object in threads servicing client requests.
   * `SessionFactory` is **immutable** and does not reflect any changes done later to the configuration.
7. The `Session` class provides the interface between the persistent data store and the application. The `Session` interface wraps a JDBC connection, which can be user-managed or controlled by Hibernate.

## Hibernate Session

### What is SessionFactory?

* It is a factory _(provider)_ of session objects.
* We use sessionfactory object to create session object
* It is a heavy weight object, therefore it has to be created only once for an application typically at application start up time one per DB per web application.
* Its immutable i.e Once Session Factory object is created, changes made to `hibernate.cfg.xml` will not be auto reflected in SF.
* A code snippet to configure a session factory can be seen [here](https://github.com/jojijoy15/Notes/blob/main/Languages/Java/01_Backend/06_ORM_Hibernate/CodeSamples/HibernateUtils.java).

### What is Session?

* Represents a wrapper around pooled out jdbc connection.
* Session object is persistance manager for the hibernate application.
* Session object is the abstraction of hibernate engine for the Hibernate application.
*   Session object provides methods to perform CRUD operations.

    | CRUD operation   | Description           |
    | ---------------- | --------------------- |
    | `save()`         | Inserting the record  |
    | `get()`/`load()` | Retrieving the record |
    | `update()`       | Updating the record   |
    | `delete()`       | Deleting the record   |

### What is Configuration Object ?

* Configuration object is used to create the `SessionFactory` object.
* Object Oriented Representation of Hibernate configuration file and mapping files _(or annotations)_ is nothing but Configuration object.
* When we call `configure()` method on configuration object, hibernate configuration file is read _(`hibernate.cfg.xml`, which is a default name from run time classpath)_ and mapping files _(or resources)_ are loaded in the memory.
* A sample configuration xml for MySQL is [here](https://github.com/jojijoy15/Notes/blob/main/Languages/Java/01_Backend/06_ORM_Hibernate/config-files/hibernate.cfg.xml).

### Why connection pooling?

* Java applications should use connection pools because,
  * Acquiring a new connection is too expensive.
  * Maintaining many idle connections is expensive.
  * Creating prepared statements is expensive.
* Hibernate provides basic or primitive connection pool which is useful only for classroom testing.
* Replace it by 3rd party vendor supplied connection pools _(eg Apache or C3P0. Hikari Connection Pool is used in spring boot)_ for production grade applications.

### Entity States

* An Hibernate Session is a set of managed entity instances that exist in a particular data store.
* It manages an Entity Instances Life Cycle.
* You manage entity instances _(or POJOs)_ by invoking operations on the entity/POJO using `EntityManager`/`Session` instance.
* Entity instances are in one of four states _(2 important aspects of entity is that, entity associates with the hibernate session & synchronizes its state with the underlying DB.)_

| State                    | Description                                                                                                                                                                                                    |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transient` _(new)_      | New entity instances have no persistent identity and are not yet associated with a hibernate session (transient)                                                                                               |
| `persistent` _(managed)_ | Managed entity instances have a persistent identity and are associated with a hibernate session. _(persisted via save() or saveOrUpdate())_ Changes to database will be done once the transaction is commited. |
| `detached`               | Detached entity instances have a persistent identity and are not currently associated with a persistence context/Hibernate session.                                                                            |
| `removed`                | Removed entity instances have a persistent identity, are associated with a persistent context and are scheduled for removal from the data store _(removed via `session.delete(obj)`)_.                         |

![Entity Life Cycle](https://574639531-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJDnjsv52I3fJ56WbLgHu%2Fuploads%2Fgit-blob-0ecf778b83d361724369304a67065cb0b98d90d4%2Fpojo-life-cycle-image.png?alt=media)

### Natural Key v/s Surrogate Key

* If you have User registeration system then you have a business rule that user email must be distinct.
* So if you want to make this as a primary key then user will have to supply this during registration.
* This is called as natural key. Since its value will be user supplied, you cannot tell hibernate to generate it for you.
  * i.e cant use `@GeneratedValue` annotation at all.
* Where, as if you say I will reserve user id only for mapping purposes _(similar to serial number)_, it need not come from user at all & can definitely be auto generate by hibernate for you and hence this is your surrogate key & can then use `@GeneratedValue` annotation which will use native database policy.
* Read more about surrogate key [here](https://www.geeksforgeeks.org/surrogate-key-in-dbms/).

## Introduction to Hibernate Caching

* While working with Hibernate web applications we will face so many problems in its performance due to database traffic. That too when the database traffic is very high. Actually, hibernate is well known just because of its high performance only. So some techniques are used to make sure to maintain its performance.
* Caching is the best technique used to reduce traffic to the database and solve traffic problem.
* The performance of Hibernate web applications is improved using caching by optimizing the database calls.
* The cache actually stores the data already loaded from the database, so that the traffic between our application and the database will be reduced when the application want to access that data again.
* At maximum, the application will work with the data in the cache only.
* Whenever some another data is needed which is not present in cache, the database will be accessed.
* Because the time needed to access the database is more compared with the time needed to access the cache by using cache, obviously the access time and traffic will be reduced between the application and the database.
* Here the cache stores only the data related to current running application.
* In order to do that, the cache must be cleared from time to time whenever the applications are changing.
