Application response timeHibernate is a great tool for integrating Java web applications with a SQL database, but what should we do when the application’s response times start increasing considerably? What should we do when we’re getting doubts whether the application will scale with the growth of our customer base?

Before spending a fortune on hosting or rewriting the code, consider analysing and improving these 7 areas of your web application.

#1 Tuning JVM memory settings

The JVM allows us to configure the amount of memory it will allocate to run our application. If the memory settings (heap size, perm gen size, etc.) are not configured properly, chances are that the Garbage Collection process runs way too often which will cause spikes in the CPU usage and halts in the execution.

#2 Optimizing configuration of JDBC datasource and Hibernate

In these configurations we can define how Hibernate and the underlying JDBC layer should behave in general. Changes (pool size, ordering, etc.) made in this section of the application may impact every single SQL query and update. Hence it’s crucial to get these settings right for the optimal performance of your application. It’s also worth mentioning here the Hibernate 2nd level cache. When the application runs the same queries over and over, caching can save up to 99% of the roundtrips to the database. There are several caching frameworks available on the market that can act as 2nd level cache providers, some of the most well-known ones are EHCacheOracle CoherenceInfinispan and Hazelcast.

#3 Optimizing Hibernate mappings

Whether we’re using annotations or XML files to configure the Hibernate mappings, a few lines of changes (lazy loading, batching, etc.) can greatly improve the performance of our application. These mappings directly impact what SQL statements will be generated and executed by Hibernate. In most cases using the default mapping configurations may just work fine, but optimizing them for the critical SQL queries and updates can substantially increase the number of round-trips to the DB and the actual time spent on execution.

#4 Optimizing Hibernate Session management

When dealing with transactions, it’s key to understand the different isolation levels and propagation types and to split the read-only and read-write DB operations into separate transactions.

#5 Adding missing DB indexes

There are a few different ways to identify the most resource intensive SQL statements, but once we have a list of them, adding the necessary indexes becomes fairly straight forward. Without those indexes, the database may have to read through entire DB tables row by row. That is one of the most resource intensive operations in the DB and it’s definitely something we want to avoid.

#6 Improving SQL statements

Some Hibernate-generated SQL statements may contain many unnecessary join operations. That is a sure-fire way to make SQL statements crawl. We must make sure to only include joins that are absolutely necessary. Another thing to keep in mind is how WHERE conditions are organized to filter the result set. Choosing the wrong order may slow down queries by an order of magnitude.

#7 Refactoring java code

One of the most typical issues in the code is the N + 1 query problem where we run a query to get a list of items and then loop through these items to run separate queries on each one of them. This anti-pattern alone can kill most attempts to scale the applications and may cost us dearly in hosting. As its fix requires code refactoring, it is one of the most complex and expensive performance issues to have.

Summary

There’s still hope when every attempt seem to be failing to fix performance issues. The above items may help identifying the main bottlenecks before they escalate into bigger problems. What performance issues are hurting your business now?

Wrong form ID
  • Andrey Stepanov

    Great collection of ideas. Thank you

    • David Kiss

      Thank you for your kind words, Andrey.