About Hibernate and JPA
Today, I will explain some of Object Relational Mapping terms. Hope that it will be helpful and clear for you. Let's start by explaining what is hibernate. ORM frameworks provide an abstraction layer over the persistence technology (relational databases like Oracle, MySQL...), allowing developers to focus on the object-oriented details of their domain model rather than lower-level database concerns. JPA is a specification of ORM and Hibernate is just one of many projects that provide an implementation of that specification. It provides an enterprise-level solution for building a persistence tier.
Hibernate framework defines the ways in which the tables and columns of a database are synchronized with the object instances and properties of JavaBeans (the created Entities).
The 4 key interfaces in any JPA application are:
- The EntityManagerFactory: which represents the configuration for the database in the application.
- The Entity Manager: It is analogous to a database connection and used to access a database in a particular unit of work. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities.
- Entity Transaction
- Query
- Unit of work: The most common pattern in a multi-user client/server application is entitymanager-per-request. In this model, a request from the client is send to the server (where the JPA persistence layer runs), a new
EntityManager
is opened, and all
database operations are executed in this unit of work. Once the work has
been completed (and the response for the client has been prepared), the
persistence context is flushed and closed, as well as the entity manager
object. You would also use a single database transaction to serve the
clients request.- This is the default JPA persistence model in a Java EE environment; injected (or looked up) entity managers share the same persistence context for a particular JTA transaction.
- Persistence Context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. With the persistence context, the entity instances and their lifecycle is managed by a particular entity manager. The scope of this context can either be the transaction or an extended unit of work.
Life Cycle of a JPA Entity
There are 5 key states that an entity might be in:- New / Transient: An object is instantiated but not yet associated with an Entity Manager and has no representation in the database.
- Managed / Persisted
- Detached: Detached entity objects are objects in a special state in which they are not managed by any EntityManager but still represent objects in the database. Detached objects are often returned from a persistence tier to the web layer where they can be displayed to the end-user in some form. Changes can be made to a detached dobject, but these changes won't be persisted to the database until the entity is reassociated with a persistence context (the entity is merged back to an EntityManager to become managed again).
- Removed
- The merge method's major task is to transfer the state from an unmanaged entity (passed as the argument) to its managed counterpart within the persistence context.
- merge deals with both new and detached entities. Merge causes either INSERT or UPDATE operation according to the sub-scenario (on the one hand it is more robust, on the other hand this robustness needn't be required.)
- persist always causes INSERT SQL operation is executed (i.e. an exception may be thrown if the entity has already been inserted and thus the primary key violation happens.)
Query Languages
- HQL (Hibernate Query Language) and JPQL (Java Persistence Query Language) both offer an object-oriented syntax for expressing query that is very similar to SQL. The two languages are interpreted at runtime, which means you cannot use the compiler to verify the correctness and integrity of a query. To adress this limitation, Hibernate includes a Criteria API, which allows queries to be expressed programmatically.
Loading in Hibernate
- Say you have a parent and that parent has a collection of children. Hibernate now can "lazy-load" the children, which means that it does not actually load all the children when loading the parent. Instead, it loads them when requested to do so. You can either request this explicitly or, and this is far more common, hibernate will load them automatically when you try to access a child.
Lazy-loading can help improve the performance significantly since
often you won't need the children and so they will not be loaded.
Also beware of the n+1-problem. Hibernate will not actually load all children when you access the collection. Instead, it will load each child individually. When iterating over the collection, this causes a query for every child. In order to avoid this, you can trick hibernate into loading all children simultaneously, e.g. by calling parent.getChildren().size().
- The fetching strategy is declared in the mapping relationship to define
how Hibernate fetch its related collections and entities. There are four fetching strategiesAlso beware of the n+1-problem. Hibernate will not actually load all children when you access the collection. Instead, it will load each child individually. When iterating over the collection, this causes a query for every child. In order to avoid this, you can trick hibernate into loading all children simultaneously, e.g. by calling parent.getChildren().size().
- fetch-”join” = Disable the lazy loading, always load all the collections and entities.
- fetch-”select” (default) = Lazy load all the collections and entities.
- batch-size=”N” = Fetching up to ‘N’ collections or entities, *Not record*. The batch-size fetching strategy is not define how many records inside in the collections are loaded. Instead, it defines how many collections should be loaded.
- fetch-”subselect” = Group its collection into a sub select statement.
Caching levels in Hibernate:
- Caching is all about application performance optimization and it sits between your application and the database to avoid the number of database hits as many as possible to give a better performance for critical applications.- The first-level cache is the Session cache and is a mandatory cache through which all requests must pass. The Session object keeps an object under its own power before committing it to the database.
- Second level cache is an optional cache and first-level cache will always be consulted before any attempt is made to locate an object in the second-level cache. The second-level cache can be configured on a per-class and per-collection basis and mainly responsible for caching objects across sessions.
Transactions:
- Transaction is based on ACID:- Atomicity: If one step fails, all the other steps fails
- Consistency: works on a consistent set of data that are hidden from other concurrency running transactions. So, data are left in a clean and consistent state after completion
- Isolation: Allows different users to work concurrently with the same data without compromise its integrity and correctness. A particular transaction should not be seen by other concurrently running transactions
- Durability: Persistent changes should not been lost even if the system fails.
- Java transaction API (JTA) specifies standard Java interfaces between a transaction manager and the parties involved in a distributed transaction system: the resource manager, the application server, and the transactional applications.
Concurrency Management in Hibernate
- Concurrency management is done through Pessimistic or Optimistic way. While the application might concurrently access the "same" (persistent identity) business object in two different persistence contexts, the two instances will actually be "different" (JVM identity). Conflicts are resolved at flush/commit time, using an optimistic approach (automatic versioning).
-The only approach that is consistent with high concurrency and high scalability is optimistic concurrency control with versioning. Version checking uses version numbers, or timestamps, to detect conflicting updates (and to prevent lost updates). Hibernate provides for three possible approaches to writing application code that uses optimistic concurrency:
- Application version checking
- Extended entity manager and automatic versioning
- Detached objects and automatic versioning
Biblio:
- http://www.objectdb.com/java/jpa/persistence/detach
- http://spitballer.blogspot.fr/2010/04/jpa-persisting-vs-merging-entites.html
- http://courses.coreservlets.com, Transaction Management and Automatic Versioning
- http://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/transactions.html
- Book: Spring persistence with Hibernate, Paul Tepper Fisher and Brian D.Murphy