Cache Named Queries with Hibernate

In the last post (see organize your named queries) a nice way to organize named queries has been proposed. The advantages of using named queries in the first place is discussed in the mentioned post, too. Hibernate offers a nice way removing a big disadvantage of named queries or to be more precise of JPQL queries in general, as compared with associations of an entity. Query results are not cached by default, neither in the first level nor in the second level cache. But you may add a query hint in order to advise hibernate to cache the results. Fortunately, like for associations, the query cache does store the ids for resulting entities, so the first and second level cache is requested for the respective objects. If the values are not present in the cache they are retrieved from the underlying resource.

The query hint may be added like this using annotations:

@Entity
@Table
@NamedQuery(name = "products.getProductsByClientId",
          query = "SELECT
                         product
               FROM
                     Product product,
                     IN(product.client) client
               WHERE
                    client.id = :clientId",
          hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") })
public class Product {
    // ...
}

Using a mapping file like introduced in the post organize your named queries looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="1.0" xmlns="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation=
        "http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd">
    <named-query name="products.getProductsByClientId">
        <query>
            SELECT
                product
            FROM
                Product product,
                IN(product.client) client
            WHERE
                client.id = :clientId
        </query>
        <hint name="org.hibernate.cacheable" value="true" />
    </named-query>
    <!-- place more queries here -->
    </named-query>
</entity-mappings>

There may be arbitrary many query hints in the query definition (see schema file of persistence.xml at xsd:complexType name="named-query" and xsd:complexType name="query-hint".

One thought to “Cache Named Queries with Hibernate”

Leave a Reply

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