The hibernate.enable_lazy_load_no_trans Anti-Pattern

Imagine having a tool that can automatically detect if you are using JPA and Hibernate properly. Hypersistence Optimizer is that tool!

Introduction

I’ve already written about the Open Session in View Anti-Pattern, so now it’s time to add another Hibernate fetching bad practices. Although the hibernate.enable_lazy_load_no_trans configuration property is a lesser-known setting, it’s good to know why you shouldn’t employ it in your data access layer code.

What does it do?

By default, this property is disabled and, to enable it, you need to provide the following configuration property:

<property 
    name="hibernate.enable_lazy_load_no_trans" 
    value="true"/>

Considering the following entities:

Post And Post Comment LazyLoad NoTrans

With this configuration property in place, the following code snippets can be executed without throwing any LazyInitializationException:

List<PostComment> comments = null;

EntityManager entityManager = null;
EntityTransaction transaction = null;
try {
    entityManager = entityManagerFactory()
        .createEntityManager();
    transaction = entityManager.getTransaction();
    transaction.begin();

    comments = entityManager.createQuery(
        "select pc " +
        "from PostComment pc " +
        "where pc.review = :review", PostComment.class)
    .setParameter("review", review)
    .getResultList();

    transaction.commit();
} catch (Throwable e) {
    if ( transaction != null && transaction.isActive())
        transaction.rollback();
    throw e;
} finally {
    if (entityManager != null) {
        entityManager.close();
    }
}
for(PostComment comment : comments) {
    LOGGER.info("The post title is '{}'", 
        comment.getPost().getTitle());
}

Without the hibernate.enable_lazy_load_no_trans configuration property in place, the comment.getPost().getTitle() line would throw a LazyInitializationException because the comments collection was not initialized, and the Persistence Context is already closed, along with the database connection that fetched the post entity.

Behind the scenes, a temporary Session is opened just for initializing every post association. Every temporary Session implies acquiring a new database connection, as well as a new database transaction.

The more association being loaded lazily, the more additional connections are going to be requested which puts pressure on the underlying connection pool. Each association being loaded in a new transaction, the transaction log is forced to flush after each association initialization.

If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.

Conclusion

Just like Open Session in View, the hibernate.enable_lazy_load_no_trans configuration property is an anti-pattern as well because it only treats the symptoms and does not solve the actual cause of the LazyInitializationException.

By properly initializing all lazy associations prior to closing the initial Persistence Context, and switching to DTO projections where entities are not even necessary, the LazyInitializationException is prevented in a much more efficient way.

FREE EBOOK

8 Comments on “The hibernate.enable_lazy_load_no_trans Anti-Pattern

  1. “a temporary Session is opened just for initializing every post association. ”
    If i have 4 comment
    [{id:1,post:1,revice:””},{id:2,post:1,revice:””},
    {id:3,post:2,revice:””},{id:4,post:2,revice:””}],
    java code
    for(PostComment comment : comments) {
    comment.getPost().getTitle();
    }
    and how many time will query the DB? 2 or 4?

    • 4 times because the first level cache is only temporarily open for the proxy initialization.

      • 1、if use second level cache,are there still 4 time or not? I think comment.getPost() is same as entitymanager.findById, so I guess it should be 2times
        2、enable_lazy_load_no_trans=true in another word is meaning open-in-view=true?

      • Have you cooperated with a Chinese publishing house (or authorized), I hope I can buy a Chinese translated version of the book.

      • There is only the English version of the book.

  2. Are you saying that this pattern should never be used? If not, why does it exist? Is there any case where it could be necessary?

    • The only reason for this is to migrate easily from EclipseLink where this anti-pattern is enabled by default.

Leave a Reply

Your email address will not be published. Required fields are marked *

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