Hibernate-Tipp: Redundante Abfragen mit Hibernates Query Cache vermeiden

Die Hibernate-Tipps-Serie bietet schnelle und einfache Lösungen zu verbreiteten Hibernate-Fragen. Dieses Mal geht es um die Verwendung des Query Cache zur Speicherung von Abfrageergebnissen.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 3 Min.
Von
  • Thorben Janssen
Inhaltsverzeichnis

Die Hibernate-Tipps-Serie bietet schnelle und einfache Lösungen zu verbreiteten Hibernate-Fragen. Dieses Mal geht es um die Verwendung des Query Cache zur Speicherung von Abfrageergebnissen.

Hibernate verwendet den First- und Second-Level Cache nicht für Abfragen. Gibt es auch eine Möglichkeit, Abfrageergebnisse in einem Cache zu speichern?

Zusätzlich zu den beiden im JPA-Standard definierten Caches bietet Hibernate den Query Cache, in dem sich Abfrageergebnisse speichern lassen. Er ist in der Standardkonfiguration deaktiviert und kann in der persistence.xml-Datei aktiviert werden. Dazu muss der Parameter hibernate.cache.use_query_cache auf "true" gesetzt und die hibernate.cache.region.factory_class-Klasse konfiguriert werden.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="my-persistence-unit">
...

<properties>
...

<!-- configure caching -->
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
</properties>
</persistence-unit>
</persistence>

Zusätzlich ist der Query Cache für die jeweilige Abfrage zu aktivieren. Dabei ist zu beachten, dass das Ergebnis einer Abfrage von der SQL-Abfrage selbst und den verwendeten Parameterwerten abhängt. Ein im Query Cache gespeichertes Abfrageergebnis lässt sich daher nur verwenden, wenn die vorherige Abfrage mit denselben Parameterwerten ausgeführt wurde.

Session s = (Session) em.getDelegate();
Query q = s.createQuery("SELECT a FROM Author a WHERE id = :id");
q.setParameter("id", 1L);
q.setCacheable(true);
log.info(q.uniqueResult());

Hibernate bietet 3 Caches die in unterschiedlichen Anwendungsszenarien zu deutlichen Performanzverbesserungen führen können. Allerdings erhält man diese Vorteile nicht geschenkt. Die Verwaltung eines Caches erzeugt zusätzlichen Aufwand und kann die Anwendung sogar verlangsamen. Mehr zum Hibernates Cache und den idealen Anwendungsszenarien, gibt es in meinem "Hibernate Performance Tuning Online Training".

Mehr als 70 solcher Rezepte zu Themen wie einfache und komplexe Mappingdefinitionen, Logging, Unterstützung von Java 8, Caching sowie die statische und dynamische Erzeugung von Abfragen gibt es in meinem Buch "Hibernate Tips: More than 70 solutions to common Hibernate problems". Es ist als Taschenbuch und E-Book auf Amazon und als PDF auf hibernate-tips.com erhältlich. ()