3 ways to set a Query timeout for JPA / Hibernate applications

In JPA (Java Persistence API) and Hibernate applications, queries can sometimes take a long time to execute, especially when working with large data sets. To avoid long-running queries, it’s important to set a query timeout, which limits the maximum amount of time that a query is allowed to run before it times out. In this tutorial, we will learn how to set a query timeout for JPA/Hibernate applications.

In general terms, most databases support statements to limit the duration of a SQL query. For example, with PostgreSQL you can set:

SET statement_timeout = 10000;

When running ORM Tools like Hibernate or JPA, there are unified ways to set a timeout for queries. Besides, you can also set a timeout limit to lock tables when using pessimistic locks. Let’s see in this tutorial which are the three ways to set a Query timeout with JPA / Hibernate. Let’s see how to do it.

Setting Query timeout in persistence.xml

This option will define a timeout limit for all statements used in your JPA applications.

<persistence>
    <persistence-unit name="my-pu">
        <properties>            
            <property name="javax.persistence.lock.timeout" value="2000"/>
            <property name="javax.persistence.query.timeout" value="2000"/>
        </properties>
    </persistence-unit>
</persistence>

With the above configuration, we have set a Query timeout of 2000 ms. We have also set a lock timeout of 2000 ms therefore locks on tables will be released after that time. It is not mandatory to use both options, as a matter of fact you can just set the “javax.persistence.query.timeout“.

Setting the Query timeout on the single Query

If you prefer to set the query timeout programmatically, you can use the setHint() method to set the timeout value for a specific query. For example, to set a query timeout of 2 seconds for a query executed using the EntityManager, you would add the following code:

    public List findCountries(String countryAbbreviation) {
      javax.persistence.Query query = em.createNamedQuery("FIND_BY_COUNTRY");
      query.setParameter("countryCode", "ITA");
      
      query.setHint("javax.persistence.query.timeout",2000);
      return query.getResultList();
    }

You can also use a fluent syntax to add the Query hint:

List<Country> countries = em.createQuery("SELECT name FROM Country c")
    .setHint("javax.persistence.query.timeout", 2000)
    .getResultList();

Handling the Query timeout exception

If a query exceeds the specified timeout value, JPA/Hibernate will throw a QueryTimeoutException. You can handle this exception in your application code to take appropriate action, such as logging the error or displaying an error message to the user. Here is an example of how to handle the QueryTimeoutException:

try {
    Query query = entityManager.createQuery("SELECT c FROM Customer c");
    query.setHint("javax.persistence.query.timeout", 30000);
    List<Customer> customers = query.getResultList();
} catch (QueryTimeoutException e) {
    // Handle the timeout exception
}

Setting the Query timeout on Find methods

Finally, if you want to set the Query timeout hint also on Find by Primary key methods, you can include the Hint in an HashMap and pass it as argument to the find method:

HashMap<String, Object> hints = new HashMap<>();
hints.put("javax.persistence.query.timeout", 2000);
 
em.find(Country.class, 1L, hints);

Using JPA 3 (Jakarta EE 9/10)

When coding Jakarta EE 9 applications, consider that the javax namespace has been replaced by the jakarta namespace. So for example if using properties in persistence.xml you should change them as follows:

<persistence>
    <persistence-unit name="my-pu">
        <properties>            
            <property name="jakarta.persistence.lock.timeout" value="2000"/>
            <property name="jakarta.persistence.query.timeout" value="2000"/>
        </properties>
    </persistence-unit>
</persistence>

Conclusion

That’s it! With these steps, you should be able to set a query timeout for your JPA/Hibernate application.

Found the article helpful? if so please follow us on Socials