19.4. Le cache de requêtes

Les résultats d'une requête peuvent aussi être placés en cache. Ceci n'est utile que pour les requêtes qui sont exécutées avec les mêmes paramètres. Pour utiliser le cache de requêtes, vous devez d'abord l'activer :

hibernate.cache.use_query_cache true

Ce paramètre amène la création de deux nouvelles régions dans le cache, une qui va conserver le résultat des requêtes mises en cache (org.hibernate.cache.StandardQueryCache) et l'autre qui va conserver l'horodatage des mises à jour les plus récentes effectuées sur les tables requêtables (org.hibernate.cache.UpdateTimestampsCache). Il faut noter que le cache de requête ne conserve pas l'état des entités, il met en cache uniquement les valeurs de l'identifiant et les valeurs de types de base (?). Le cache de requête doit toujours être utilisé avec le cache de second niveau pour être efficace.

La plupart des requêtes ne retirent pas de bénéfice pas du cache, donc par défaut les requêtes ne sont pas mises en cache. Pour activer le cache, appelez Query.setCacheable(true). Cet appel permet de vérifier si les résultats sont en cache ou non, voire d'ajouter ces résultats si la requête est exécutée.

Si vous avez besoin de contrôler finement les délais d'expiration du cache, vous pouvez spécifier une région de cache nommée pour une requête particulière en appelant Query.setCacheRegion().

List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
    .setEntity("blogger", blogger)
    .setMaxResults(15)
    .setCacheable(true)
    .setCacheRegion("frontpages")
    .list();

Si une requête doit forcer le rafraîchissement de sa région de cache, vous devez appeler Query.setCacheMode(CacheMode.REFRESH). C'est particulièrement utile lorsque les données peuvent avoir été mises à jour par un processus séparé (e.g. elles n'ont pas été modifiées par Hibernate). Cela permet à l'application de rafraîchir de manière sélective les résultats d'une requête particulière. Il s'agit d'une alternative plus efficace à l'éviction d'une région du cache à l'aide de la méthode SessionFactory.evictQueries().