You are on page 1of 42

Hibernate

Hibernate is a Java framework that simplifies the development of Java


application to interact with the database. It is an open source, lightweight, ORM
(Object Relational Mapping) tool. Hibernate implements the specifications of JPA
(Java Persistence API) for data persistence.

An ORM tool simplifies the data creation, data manipulation and data
access. It is a programming technique that maps the object to the data
stored in the database.
Advantages of Hibernate Framework

Following are the advantages of hibernate framework:


1) Open Source and Lightweight
Hibernate framework is open source under the LGPL license and lightweight.
2) Fast Performance
The performance of hibernate framework is fast because cache is internally used in hibernate
framework. There are two types of cache in hibernate framework first level cache and second level cache.
First level cache is enabled by default.
3) Database Independent Query
HQL (Hibernate Query Language) is the object-oriented version of SQL. It generates the database
independent queries. So you don't need to write database specific queries. Before Hibernate, if database is
changed for the project, we need to change the SQL query as well that leads to the maintenance problem.
4) Automatic Table Creation
Hibernate framework provides the facility to create the tables of the database automatically. So there is
no need to create tables in the database manually.
5) Simplifies Complex Join
Fetching data from multiple tables is easy in hibernate framework.
6) Provides Query Statistics and Database Status
Hibernate supports Query cache and provide statistics about query and database status.
Hibernate Architecture

The Hibernate architecture includes many objects such as persistent object,


session factory, transaction factory, connection factory, session, transaction etc.

The Hibernate architecture is categorized in four layers:

• Java application layer


• Hibernate framework layer
• Backhand api layer
• Database layer
Elements of Hibernate Architecture
For creating the first hibernate application, we must know the elements of Hibernate architecture. They are
as follows:

SessionFactory
The SessionFactory is a factory of session and client of ConnectionProvider. It holds second level cache
(optional) of data. The SessionFactory interface provides factory method to get the object of Session.

Session
The session object provides an interface between the application and data stored in the database. It is a
short-lived object and wraps the JDBC connection. It is factory of Transaction, Query and Criteria. It holds a first-
level cache (mandatory) of data. The Session interface provides methods to insert, update and delete the object.
It also provides factory methods for Transaction, Query and Criteria.

Transaction
The transaction object specifies the atomic unit of work. It is optional. The org.hibernate.Transaction
interface provides methods for transaction management.
Hibernate using Annotation

The hibernate application can be created with annotation. There are many annotations that can be used to
create hibernate application such as @Entity, @Id, @Table etc.

Hibernate Annotations are based on the JPA 2 specification and supports all the features.
All the JPA annotations are defined in the javax.persistence package. Hibernate EntityManager
implements the interfaces and life cycle defined by the JPA specification.
Entity
Entities in JPA are nothing but POJOs representing data that can be persisted to the database. An entity
represents a table stored in a database. Every instance of an entity represents a row in the table.

The Entity Annotation
Let's say we have a POJO called Student which represents the data of a student and we would like to
store it in the database.
In order to do this, we should define an entity so that JPA is aware of it.
So let's define it by making use of the @Entity annotation. We must specify this annotation at the class level. We
must also ensure that the entity has a no-arg constructor and a primary key: 

The entity name defaults to the name of the class. We can change its name using the name element.
The Id Annotation

Each JPA entity must have a primary key which uniquely identifies it. The @Id annotation defines the
primary key. We can generate the identifiers in different ways which are specified by
the @GeneratedValue annotation.

We can choose from four id generation strategies with the strategy element. The value can be AUTO,
TABLE, SEQUENCE, or IDENTITY.
AUTO Generation

If we're using the default generation type, the persistence provider will determine values based on the type
of the primary key attribute. This type can be numerical or UUID.
For numeric values, the generation is based on a sequence or table generator, while UUID values will use
the UUIDGenerator.
Let's see an example of mapping an entity primary key using AUTO generation strategy:

In this case, the primary key values will be unique at the database level.
An interesting feature introduced in Hibernate 5 is the UUIDGenerator. To use
this, all we need to do is declare an id of
type UUID with @GeneratedValue annotation:

Hibernate will generate an id of the form “8dd5f315-


9788-4d00-87bb-10eed9eff566”.
IDENTITY Generation

This type of generation relies on the IdentityGenerator which expects values generated by


an identity column in the database, meaning they are auto-incremented.
To use this generation type, we only need to set the strategy parameter:

One thing to note is that IDENTITY generation disables batch updates.


SEQUENCE Generation

To use a sequence-based id, Hibernate provides the SequenceStyleGenerator class.


This generator uses sequences if they're supported by our database, and switches to table generation if
they aren't.
To customize the sequence name, we can use the @GenericGenerator annotation
with SequenceStyleGenerator strategy:

In this example, we've also set an initial value for


the sequence, which means the primary key generation
will start at 4.
SEQUENCE is the generation type
recommended by the Hibernate documentation.
The generated values are unique per
sequence. If you don't specify a sequence name,
Hibernate will re-use the same hibernate_sequence for
different types.
TABLE Generation

The TableGenerator uses an underlying database table that holds segments of identifier generation values.
Let's customize the table name using the @TableGenerator annotation:

In this example, we can see that other attributes


such as the pkColumnName and valueColumnName can
also be customized.
The disadvantage of this method is that it doesn't
scale well and can negatively affect performance.
To sum up, these four generation types will
result in similar values being generated but use
different database mechanisms.
The Table Annotation

In most cases, the name of the table in the database and the name of the entity will not be the same. In
these cases, we can specify the table name using the @Table annotation:

If we do not use the @Table annotation, the name of the entity will be considered the
name of the table.
The Column Annotation

Just like the @Table annotation, we can use the @Column annotation to mention the details of a column in
the table.
The @Column annotation has many elements such as name, length, nullable, and unique.

The name element specifies the name of the column in the table. The length element


specifies its length. The nullable element specifies whether the column is nullable or not, and
the unique element specifies whether the column is unique.
If we don't specify this annotation, the name of the field will be considered the name of the
column in the table.
The Transient Annotation

Sometimes, we may want to make a field non-persistent. We can use the @Transient annotation to do


so. It specifies that the field will not be persisted.
For instance, we can calculate the age of a student from the date of birth.
So let's annotate the field age with the @Transient annotation:

As a result, the field age will not be persisted to the table.


@OneToOne relationship using a Foreign Key

Let's suppose we are building a user management system, and


our boss asks us to store a mailing address for each user. A user will
have one mailing address, and a mailing address will have only one
user tied to it.
This is an example of a one-to-one relationship, in this case
between user and address entities.
Note that we place the @OneToOne annotation on the related entity field, Address.
Also, we need to place the @JoinColumn annotation to configure the name of the column in the users table
that maps to the primary key in the address table. If we don't provide a name, Hibernate will follow some rules to
select a default one.
Finally, note in the next entity that we won't use the @JoinColumn annotation there. This is because we
only need it on the owning side of the foreign key relationship. Simply put, whoever owns the foreign key
column gets the @JoinColumn annotation.
The Address entity turns out a bit simpler:

We also need to place the @OneToOne annotation here


too. That's because this is a bidirectional
relationship. The address side of the relationship is
called the non-owning side. 
@OneToOne relationship using a Shared Primary Key

In this strategy, instead of creating a new column address_id, we'll


mark the primary key column (user_id) of the address table as
the foreign key to the users table:
The mappedBy attribute is now moved to the User class since the foreign key is now
present in the address table. We've also
added the @PrimaryKeyJoinColumn annotation, which indicates that the primary key
of the User entity is used as the foreign key value for the associated Address entity.

We still have to define an @Id field in the Address class. But note that this references
the user_id column, and it no longer uses the @GeneratedValue annotation. Also, on the
field that references the User, we've added the @MapsId annotation, which indicates
that the primary key values will be copied from the User entity.
@OneToOne relationship using a Join Table

One-to-one mappings can be of two types: optional and mandatory. So far,


we've seen only mandatory relationships.

Now let's imagine that our employees get associated with a workstation. It's
one-to-one, but sometimes an employee might not have a workstation and vice
versa.
@OneToMany relationship

one-to-many mapping means that one row in a table is mapped to multiple rows in another table.
Unidirectional @OneToMany
by default, that’s how the
unidirectional @OneToMany
association works, and this is
how it looks from a database
perspective:
Unidirectional @OneToMany with @JoinColumn
Bidirectional @OneToMany
Thank you :)

Ne vedem la sesiunea viitoare!

You might also like