Chapter 4. Hibernate with Spring

While developing a real-world application using the Spring Framework, we often store and retrieve data to and from the relational database in the form of objects. These objects are non-scalar values that can't be directly stored and retrieved to and from the database, as only scalar values can be directly stored in the relational database, which is technically defined as impedance mismatch. In the previous section, we took a look at using JDBC in Spring applications.

Data persistence is the ability to preserve the state of an object so that it can regain the same state in the future. In this chapter, we will be focused on saving in-memory objects into the database using ORM tools that have wide support in Spring Hibernate.

As we have understood from earlier chapters, Spring uses POJO-based development and also uses declarative configuration management to overcome EJB's clumsy and heavy setup (EJB architecture was released a lot of time ago and is just not feasible).

The developer community realized that the development of data access logic could be easy using a simple, lightweight POJO-based framework. This resulted in the introduction of ORM. The objective of ORM libraries was to close the gap between the data structure in the RDBMS and the object-oriented model in Java. It helped developers focus on programming with the object model.

Hibernate is one of the most successful ORM libraries available in the open source community. It won the heart of the Java developer community with features such as its POJO-based approach, support of relationship definitions, and ease of development.

This chapter will cover the basic ideas and main use cases of Hibernate in Spring when developing data access logic. Hibernate is an extensive ORM library, so it is not possible to cover every aspect of Hibernate in just one chapter.

The list of topics that will be covered in this chapter are:

  • Why Object/Relational Mapping (ORM)?
  • Introducing ORM, O/RM, and O/R mapping
  • Introducing Hibernate
  • Integrating Hibernate with the Spring Framework
  • Hibernate Criteria Query Language (HCQL)

Why Object/Relational Mapping?

Object-oriented languages such as Java represent data as an interconnected Graph of Objects, whereas relational database systems represent data in a table-like format. Relational databases normally work with tables; data is stored in different types of tables. Java implements the object model whereas relational database management systems (RDBMS) implement the relational model. Because both the models are quite different in the way they represent data, when we load or store graphs of objects using relational databases, it causes mismatch problems. Refer to the following figure for clarity:

Why Object/Relational Mapping?

Enterprise-level applications implemented using object-oriented languages such as Java manage the data in the form of objects. Most of these applications use relational databases such as RDBMS to maintain persistence of data in the form of tables with rows and columns. Implementing the data access layer using low-level APIs such as JDBC includes huge boilerplate code, which affects the productivity of the system, increasing the cost of application development.

Let's say we have an Employee class in our application, having fields named empId, firstName, dateOfBirth, and phone. In the running application, there will be many instances of this class in memory. Say we have four employee objects in memory and we want to save these employee objects into the relational database as a common database.

We will be having an Employee table with column names the same as the fields in the Employee class. Each of these employee objects contains data for a particular employee, which will be persisted as rows in that table. A class corresponds to a table and an object of this class corresponds to a row in that table, as shown here:

Why Object/Relational Mapping?

This is what we have followed as our traditional approach in Java applications over the years. We connect to a database using a JDBC connection and create a SQL query to perform an INSERT operation. So, that data will execute in the form of SQL queries to perform INSERT. Similarly, we create an object using setter methods after performing the SELECT query. By using boilerplate code, the object will get converted into a data model and vice versa, which results in a painful mapping process. This is a common problem in every Java application that has a persistence layer and that connects to the database in order to save and retrieve values.

Mapping relationships is another issue that needs to be addressed. Let's say we have another table called Address table and an object called address object. Let's also say the employee object has a reference to this address object. In this case, the primary key of the Address table will be mapped to a foreign key of the Employee table.

Another issue that needs to be addressed is data types. Let's say we have an object with a Boolean data type whereas most of the database doesn't have Boolean data type and probably used as char for Y/N or integer for 0/1, which need to be handled during data type conversion while writing code.

Managing changes to object state is another issue that needs to be addressed. If there are some changes to object state, then we need to manually execute the procedure to make these changes and we also need to reframe the SQL queries and update the database by ourselves.

To solve these problems, we need a customizable generic system that can take the responsibility of filling the gap between the object and relational models for our application. This requirement has resulted in the introduction of ORM, which provides an elegant way to handle the mentioned issues.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.151.153