JPA Buddy
announcement - icon

JPA is huge! It covers nearly every aspect of communication between relational databases and the Java application and is deeply integrated into all major frameworks.

If you're using IntelliJ, JPA Buddy is super helpful. The plugin gently guides you through the subtleties of the most popular JPA implementations, visually reminds you of JPA features, generates code that follows best practices, and integrates intelligent inspections to improve your existing persistence code.

More concretely, it provides powerful tooling to generate Spring Data JPA repositories and methods, Flyway Versioned Migrations, Liquibase Differential Changelogs, DDL and SQL statements, DTO objects, and MapStruct interfaces.

Oh, and it actually generates JPA entities from an existing database and gradually update the data model as the database evolves! Yeah.

>> Become a lot more productive with JPA Buddy

Persistence Top Fauna

Building IoT Applications Using Fauna and Spring

Spring Top – Temp

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

Lightrun – Third Party Code

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Overview

When working with an ORM, data fetching/loading can be classified into two types: eager and lazy.

In this quick tutorial, we are going to point out differences and show how we can use these in Hibernate.

2. Maven Dependencies

In order to use Hibernate, let's first define the main dependency in our pom.xml:


The latest version of Hibernate can be found here.

3. Eager and Lazy Loading

The first thing that we should discuss here is what lazy loading and eager loading are:

  • Eager Loading is a design pattern in which data initialization occurs on the spot.
  • Lazy Loading is a design pattern that we use to defer initialization of an object as long as it's possible.

Let's see how this works.

First, we'll look at the UserLazy class:

@Table(name = "USER")
public class UserLazy implements Serializable {

    @Column(name = "USER_ID")
    private Long userId;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    private Set<OrderDetail> orderDetail = new HashSet();

    // standard setters and getters
    // also override equals and hashcode


Next, we'll see the OrderDetail class:

@Table (name = "USER_ORDER")
public class OrderDetail implements Serializable {
    private Long orderId;
    @ManyToOne(fetch = FetchType.LAZY)
    private UserLazy user;

    // standard setters and getters
    // also override equals and hashcode


One User can have multiple OrderDetails. In eager loading strategy, if we load the User data, it will also load up all orders associated with it and will store it in a memory.

But when we enable lazy loading, if we pull up a UserLazy, OrderDetail data won't be initialized and loaded into a memory until we make an explicit call to it.

In the next section, we'll see how we implement the example in Hibernate.

4. Loading Configuration

Let's look at how to configure fetching strategies in Hibernate.

We can enable Lazy Loading by using this annotation parameter:

fetch = FetchType.LAZY

For Eager Fetching, we use this parameter:

fetch = FetchType.EAGER

To set up Eager Loading, we have used UserLazy‘s twin class called UserEager.

In the next section, we will look at the differences between the two types of fetching.

5. Differences

As we mentioned, the main difference between the two types of fetching is the moment when data gets loaded into a memory.

Let's have a look:

List<UserLazy> users = sessionLazy.createQuery("From UserLazy").list();
UserLazy userLazyLoaded = users.get(3);
return (userLazyLoaded.getOrderDetail());

With the lazy initialization approach, orderDetailSet will get initialized only when we explicitly call it, using a getter or some other method:

UserLazy userLazyLoaded = users.get(3);

But with an eager approach in UserEager, it will be initialized immediately in the first line:

List<UserEager> user = sessionEager.createQuery("From UserEager").list();

For lazy loading, we use a proxy object and fire a separate SQL query to load the orderDetailSet.

The idea of disabling proxies or lazy loading is considered a bad practice in Hibernate. It can result in fetching and storing a lot of data, irrespective of the need for it.

We can use the following method to test the functionality:


Now let's have a look at the queries generated in either case:

<property name="show_sql">true</property>

The above setting in the fetching.hbm.xml shows the generated SQL queries. If we look at a console output, we can see generated queries.

For Lazy Loading, here's the query generated to load the User data:

select user0_.USER_ID as USER_ID1_0_,  ... from USER user0_

However, in eager loading, we saw a join made with USER_ORDER:

select orderdetai0_.USER_ID as USER_ID4_0_0_, orderdetai0_.ORDER_ID as ORDER_ID1_1_0_, orderdetai0_ ...
  from USER_ORDER orderdetai0_ where orderdetai0_.USER_ID=?

The above query is generated for all Users, which results in much more memory use than in the other approach.

6. Advantages and Disadvantages

6.1. Lazy Loading


  • Much smaller initial load time than in the other approach
  • Less memory consumption than in the other approach


  • Delayed initialization might impact performance during unwanted moments.
  • In some cases we need to handle lazily initialized objects with special care, or we might end up with an exception.

6.2. Eager Loading


  • No delayed initialization-related performance impacts


  • Long initial loading time
  • Loading too much unnecessary data might impact performance

7. Lazy Loading in Hibernate

Hibernate applies lazy loading approach on entities and associations by providing a proxy implementation of classes.

Hibernate intercepts calls to an entity by substituting it with a proxy derived from an entity’s class. In our example, missing requested information will be loaded from a database before control is ceded to the User class implementation.

We should also note that when the association is represented as a collection class (in the above examples, it is represented as Set<OrderDetail> orderDetailSet), a wrapper is created and substituted for an original collection.

To know more about proxy design pattern, refer here.

8. Conclusion

In this article, we showed examples of the two main types of fetching used in Hibernate.

For advanced expertise, check the official website of Hibernate.

To get the code discussed in this article, please have a look at this repository.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

Persistence bottom

Get started with Spring Data JPA through the reference Learn Spring Data JPA course:

Persistence footer banner
Comments are closed on this article!