Daten mit Hilfe der Java Persistence API in der Datenbank zu speichern stellt den Standard für Java Enterprise Anwendungen dar. Der Applikationsserver stellt alle benötigten Bibliotheken bereits zur Verfügung und die Verwendung ist so einfach, dass sie innerhalb kürzester Zeit erlernt werden kann. Spannend wird es immer erst dann, wenn die Anforderungen steigen, z.B. weil das Domainmodell sehr komplex, die Datenmenge besonders groß oder die geforderten Antwortzeiten sehr kurz sind. Auch hierfür bietet JPA in der Regel gute Lösungen und wenn das nicht ausreicht, können wir immer noch auf Hibernate-spezifische Features zurückgreifen. Dazu sind allerdings deutlich detailliertere Kenntnisse erforderlich. Einige Beispiele dafür sind Caches, Entity Graphen und Attribute Converter. Wir werden uns genauer ansehen, wie wir diese und andere Features nutzen können, um auch komplexere Anforderungen mit Hilfe von JPA umzusetzen und wann wir auf Hibernate-spezifische Features zurückgreifen müssen.
Hierfür werden grundlegende Kenntnisse in der Verwendung von JPA und Hibernate vorausgesetzt.
10. • Ein Kunde meldet ein langsames System
• Der DBA fragt nach dem Grund für sehr viele (ähnliche) Abfragen
• Schlechte Performance beim Test der Anwendung
• Entwickler sieht auffällige Statistiken im Log
www.thoughts-on-java.org
Performanceprobleme
22. • Statische Definition im Mapping
• Fragestellungen
• Wann soll geladen werden? FetchType
• Wie soll geladen werden? FetchMode
www.thoughts-on-java.org
Fetch-Stratgien
24. • Lazy
• Relation wird bei erstem Zugriff geladen
• Default für to-many Relationen
• Verwendet Proxies für to-one Relationen
• Eager
• Relation wird sofort geladen
• Default für to-one Relationen
www.thoughts-on-java.org
FetchType
25. • Hibernate erzeugt Proxy für lazy to-one-Relationen
• Proxy ist Subklasse der Entity
• Instanceof möglich
• Typecast auf Subklasse nicht möglich
• Alternative: bytecode enhancement ohne Proxy
www.thoughts-on-java.org
To-onemitProxy
28. • Hibernate spezifisch
• Definiert wie Relationen geladen werden
• JOIN = im selben SELECT
• SELECT = 1 SELECT je Entity der Relation
• SUBSELECT = 1 SELECT für alle Entities der Relation
• BATCH = mehrere Entities der Relation je SELECT
www.thoughts-on-java.org
FetchMode
30. • To-many-Relationen
• Default in Annotationen belassen (meist FetchType.LAZY)
• Eager fetching, wenn benötigt für Query definieren
• To-one-Relationen
• Einzeln prüfen, meist ist der default OK
www.thoughts-on-java.org
Empfehlung
37. • Vorteile:
• EntityManager lädt Relation in der selben Abfrage
• Nachteile:
• Spezielle Abfrage für jeden Use Case erforderlich
• Bildet kartesisches Produkt
www.thoughts-on-java.org
FetchJoin
38. • Neu in JPA 2.1
• Definiert einen zu ladenden Entitätsgraphen
• @NamedEntityGraph
• @NamedAttributeNode
• @NamedSubGraph
www.thoughts-on-java.org
NamedEntityGraph
39. • Fetchgraph
• Elemente des Graphen werden EAGER geladen
• Alle anderen werden LAZY geladen
• Loadgraph
• Elemente des Graphen werden EAGER geladen
• Alle anderen werden mit ihrem jeweiligen FetchType geladen
• ACHTUNG: Hibernate behandelt beides gleich!
• HHH-8776
www.thoughts-on-java.org
NamedEntityGraph
44. • Vorteile:
• Queryspezifisches EAGER-loading
• Definition des Graphen unabhängig von der Abfrage
• Graph kann zur Laufzeit definiert werden
• Nachteile:
• Bildet kartesisches Produkt
www.thoughts-on-java.org
EntityGraph
52. • Sessionübergreifender Speicher für Entities
• Im default deaktiviert
• persistence.xml oder EntityManagerFactory
• Zugriff erfolgt transparent
• Muss nicht durch den Persistence Provider bereitgestellt werden
• u.U. nicht portierbar
www.thoughts-on-java.org
2ndLevelCache
53. • Shared Cache Mode
• ALL alle Entities werden gecached
• NONE keine Entities werden gecached
• ENABLE_SELECTIVE Caching muss für Entities aktiviert werden
• DISABLE_SELECTIVE Caching kann für Entities deaktiviert werden
• UNSPECIFIED Verwendet das default caching des
PersistenceProviders
www.thoughts-on-java.org
2ndLevelCache
54. • Speichert die Entities in ‚dehydrated‘-Form
• Nur die Eigenschaften der Entity, nicht die Entity selbst
• 1 [„Joshua“, „Bloch“, 0]
• Relationen werden nicht mit gespeichert
• Caching mit @org.hibernate.annotations.Cache möglich
www.thoughts-on-java.org
2ndLevelCache
56. • Verwendung des Cache konfigurieren
• Cache Retrieve Mode
• Definiert wie Daten aus dem Cache gelesen werden
• Cache Store Mode
• Definiert wie Daten in den Cache geschrieben werden
www.thoughts-on-java.org
2ndLevelCache
57. • Cache Retrieve Mode
• CacheRetrieveMode.USE (default)
• Daten werden aus Cache gelesen
• CacheRetrieveMode.BYPASS
• Daten werden aus DB gelesen
www.thoughts-on-java.org
2ndLevelCache
58. • Cache Store Mode
• CacheStoreMode.USE (default)
• Cache wird beim commit erzeugt oder aktualisiert
• Aktualisierung wird bei nur lesendem Zugriff nicht erzwungen
• CacheStoreMode.BYPASS
• Cache wird nur aktualisiert, nicht angelegt
• CacheStoreMode.REFRESH
• Cache wird beim commit erzeugt oder aktualisiert
• Aktualisierung wird bei nur lesendem Zugriff erzwungen
www.thoughts-on-java.org
2ndLevelCache
63. • Hibernate spezifisch
• Sessionübergreifender Speicher von Abfrageergebnissen
• Im default deaktiviert
• persistence.xml: hibernate.cache.use_query_cache = true
• Caching muss für Query aktiviert werden
• org.hibernate.Query.setCacheable(true)
• @NamedQuery(… hints =
@QueryHint(name="org.hibernate.cacheable", value="true"))
www.thoughts-on-java.org
QueryCache
64. • Speichert Ergebnis für Abfrage mit Parametern
• [„FROM Author WHERE id=?“, 1] [1]
• Speichert nur Referenzen auf Entitäten oder Skalare
• Immer mit 2nd Level Cache kombinieren
www.thoughts-on-java.org
QueryCache
66. • Nur Daten mit geringer Änderungsrate cachen
• Cache nicht ohne Benchmark einführen
• Query Cache und 2nd Level Cache gemeinsam nutzen
• Konfigurationen aufeinander abstimmen
www.thoughts-on-java.org
Empfehlung
67. • JSR 338: JavaTM Persistence API, Version 2.1
http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-
spec/index.html
• Hibernate Reference Documentation
http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/
• Hibernate Developer Guide
http://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/
• Hibernate ORM: Tips, Tricks and Performance Techniques by Brett
Meyer http://de.slideshare.net/brmeyer/hibernate-orm-
performance-31550150
• Java Persistence with Hibernate Second Edition by Christian Bauer,
Gaving King, Gary Gregory
www.thoughts-on-java.org
Quellen
68. • Java Platform, Enterprise Edition: The Java EE Tutorial
https://docs.oracle.com/javaee/7/tutorial/index.html
• Hibernate: Truly Understanding the Second-Level and Query Caches
http://www.javalobby.org/java/forums/t48846.html
www.thoughts-on-java.org
Quellen