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

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.

Setting Query timeout in persistence.xml

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

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

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“.

Please notice: the above properties are hints which might be (or might not be) used by your persistence provider. It’s up to the persistence provider.

Setting the Query timeout on the single Query

If you want to set the Query timeout hint on a single Query, then you can set it as in this example:

    public List findCountries(String countryAbbreviation) {
      javax.persistence.Query query = em.createNamedQuery("FIND_BY_COUNTRY");
      query.setParameter("countryCode", "ITA");
      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)

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)

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-unit name="my-pu">
            <property name="jakarta.persistence.lock.timeout" value="2000"/>
            <property name="jakarta.persistence.query.timeout" value="2000"/>