0

hibernate excecutes a select statement for each field of the objects being retrieved. This results in 30 seconds to complete a query or a login action on aws RDS instance and 1.32 seconds on localhost.

All of my fields are lazily fetched and when I need one or more of the fields I fetch the object requested with the fields initialized with Hibernate.initialize().

Example.java

public Badge getWithBadge(int id, String field) {

    Session session = session();
    try {
        CriteriaBuilder builder = session.getCriteriaBuilder();
        CriteriaQuery<Badge> crit = builder.createQuery(Badge.class);
        Root<Badge> root = crit.from(Badge.class);
        crit.select(root).where(builder.equal(root.get("id"), id));
        Query<Badge> q = session.createQuery(crit);

        Badge result = q.getSingleResult();

        if (field.equals("users")) {
            Hibernate.initialize(result.getUsers());
        } else if (field.equals("equipedBy")) {
            Hibernate.initialize(result.getEquipedBy());
        }

        session.close();
        return result;
    } catch (Exception e) {
        retrievalFailed(session, e);
        return null;
    }
}

I'd like to decrease the number of queries being excecuted preferably without using hql prepared statements.

DisplayName
  • 89
  • 1
  • 2
  • 12

1 Answers1

0

Use join fetch to avoid N+1 performance problem. join fetch in JPQL will result in generating SQL join in underlying native statement.

Criteria API method for join fetch:

root.fetch("users", JoinType.LEFT);
Peter Šály
  • 2,848
  • 2
  • 12
  • 26