Query Caching in JPA 1.0 mit EclipseLink
Überblick Caching
Caching kann ein wichtiger Mechanismus zur Steigerung der Performance einer Software-Applikation sein. Abhängig von der Applikationsart bietet sich Caching insbesondere an, um die Anzahl der Datenbankzugriffe einer Applikation zu reduzieren.
Mit JPA 2.0 (Java Persistence API) wurden einige Möglichkeiten für das Caching standardisiert. Allerdings findet in der Praxis in den meisten Fällen noch die Version 1.0 Verwendung, da die gängigen Applikation-Server die neue JPA-Version oftmals nur in Preview-Releases anbieten.
Aufrund der nur rudimentären Unterstützung von JPA 1.0 für Caching, haben einige JPA-Implementierungen eigene Erweiterungen eingeführt, die über den Standard hinausgehen.
Dies gilt auch für die weit verbreitete Open Source Implementierung EclipseLink [1], die auch wir in einem Projekt einsetzen.
Beispiel für Cache Konfiguration
Die Cache-Definitionen können in EclipseLink in den Dateien persistence.xml, eclipselink-orm.xml sowie an den Entities erfolgen.
Da sich Caching nicht für alle Datenbankobjekte anbietet, ist es in der Regel sinnvoll Caches auf Ebene der einzelnen Entities zu definieren.
In unserem Projekt kommt Caching für einige Konfigurations-Tabellen zum Einsatz auf die lesend zugegriffen wird und die bei Änderungen direkt in der Datenbank manipuliert werden.
Nachfolgend ist die Beispiel-Konfiguration einer Entität aufgeführt:
@Cache(
type=CacheType.SOFT, // Cacheinhalte werden freigegeben, wenn Speicher ausgeht
size=200, // Maximal 200 Objekte
expiry=600000, // Gültigkeit von 10 Minuten
)
In der Datei persistence.xml wurden die entsprechenden Einstellungen laut Dokumentation vorgenommen. Die Tests zeigten zunächst, dass der Cache einwandfrei funktionierte und auch korrekt nach der abgelaufenen Zeitspanne invalidiert wurde.
Allerdings stellte sich bei weiteren Tests heraus, dass nicht nur die einzelnen gewünschten Entitäten gecached wurden, sondern alle Entitäten in der Applikation.
Nach einigigen Versuchen und weiteren Tests führte der nachfolgend aufgeführte Auszug der Datei persistence.xmlzum Erfolg. Insbesondere musste die Default-Größe für Caches auf 0 gesetzt werden. Außerdem war das Deaktivieren des sogenannten Parent Session Cache für alle Entitäten, die nicht gecacht werden sollen, nötig.
<property name="eclipselink.cache.size.default" value="0">
<property name="eclipselink.cache.shared.default.Person" value="false">
<property name="eclipselink.cache.shared.default.Property" value="true">
<property name="eclipselink.cache.shared.default.Tasks" value="true">
Fazit
Nach einigen Konfigurationsschwierigkeiten funktioniert das Caching mit EclipseLink einwandfrei. Um böse Überraschungen zu vermeiden, empfiehlt es sich wie in unserem Fall das Caching durchgehend zu Testen.
Links
[1] EclipseLink