JPA Pitfalls (12): Lazy Loading of Relationships in a Loop

This blog article is part of a “series of blog articles” about common pitfalls using JPA and ways to avoid them. In this article, we describe a potential performance problem when loading relationships in a loop.

The following code pattern easily runs into performance problems. It retrieves a list of entity instances from the database and for each entity accesses a number of attributes including lazy loaded relationships.

List<Employee> emps = // Retrieve employees from DB
for (Employee e : emps) {
    showEmployeeDetails(
        e.getFirstname(), e.getLastname(),
        e.getDepartment() == null ? 
            e.getDepartment().getName() : null,
        e.getInsurance() == null ? 
            e.getInsurance().getCarrier() : null);
}

In case the relationships department and insurance in Employee are defined as lazy loaded, each iteration will execute two database queries.

It is better to load all the required data with a single database query. The query does not return entities, instead it retrieves just the required fields and navigates the relationships as part of the query:

List<Object[]> empDetails = em.createQuery(
    "SELECT e.firstname, e.lastname, d.name, i.carrier " +
    "FROM Employee e LEFT OUTER JOIN e.department d " + 
    "LEFT OUTER JOIN e.insurance i").getResultList();
for (Object[] empDetail : empDetails) {
    showEmployeeDetails(empDetail[0], empDetail[1], 
                       empDetail[2], empDetail[3]);
}

Recommendation: Use a JPQL query to load specific fields including fields of associated entities.

You can find an example of this pitfall and its solution in the class LoadingRelationshipsExperiment in this project: https://github.com/akquinet/jpapitfalls.git.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.