View
932
Download
1
Category
Preview:
Citation preview
Effiziente Datenpersistierungmit JPA 2.1
www.thoughts-on-java.org
Thorben Janssen
• Senior Entwickler und Architekt @ Qualitype GmbH
• CDI 2.0 (JSR 365) Expert Group Mitglied
• Twitter: @thjanssen123
• Blog: www.thoughts-on-java.org
www.thoughts-on-java.org
Beispielanwendung
www.thoughts-on-java.org
www.thoughts-on-java.org
An
wen
du
ng
Was bedeutet Effizienz?
www.thoughts-on-java.org
Performance
SpeicherplatzProduktivität Xwww.thoughts-on-java.org
X
Effi
zien
z
Performance
www.thoughts-on-java.org
• Frühzeitiges Erkennen von Performanceproblemen
• Typische Ursachen von Performanceproblemen
• Performanceprobleme beheben und vermeiden
www.thoughts-on-java.org
Perf
orm
ance
Auftreten von Performanceproblemen
www.thoughts-on-java.org
• 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
Perf
orm
ance
pro
ble
me
Hibernate Statistics
www.thoughts-on-java.org
• Über Systemproperty aktivieren:
hibernate.generate_statistics = true
• Logging konfigurieren:
org.hibernate.stat = DEBUG
www.thoughts-on-java.org
Hib
ern
ate
Stat
isti
cs
Demo (Projekt Model)
www.thoughts-on-java.org
Ursachen von Performanceproblemen
www.thoughts-on-java.org
• Langsame Select-Statements
• Falsche Fetch-Strategie
• Fehlendes Caching
• Laden nicht benötigter Daten
• Datensätze einzeln löschen oder ändern
• Logik in der Anwendung anstatt der Datenbank/Abfrage
www.thoughts-on-java.org
Häu
fige
Urs
ach
en
1. Langsame Select-Statements
www.thoughts-on-java.org
• Meistens kein „echtes“ JPA- oder Hibernateproblem
• Erzeugtes SQL überprüfen
• Indexe überprüfen
• Ausführungsplan des Statements überprüfen
• Ggf. Ergebnismenge beschränken (paging)
• Statement optimieren
• Native SQL-Statements verwenden, wenn JPQL nicht ausreicht
www.thoughts-on-java.org
Lan
gsam
e Se
lect
s
• Schnellere Abfragen durch echtes SQL
• JPQL unterstützt nur ein Subset von SQL
• Datenbankspezifische SQL-Features
• Native Query liefert Object[] für jede Ergebniszeile
• Erfordert programmatisches oder deklaratives Mapping
www.thoughts-on-java.org
Nat
ive
Qu
ery
• Deklaratives Mapping für Abfrageergebnisse
• Unterstützte Zieltypen:
• Entities
• Value Objekte
• Skalare
www.thoughts-on-java.org
Res
ult
SetM
app
ing
Demo (Projekt NativeQuery)
www.thoughts-on-java.org
2. Fetch-Strategien
www.thoughts-on-java.org
• Statische Definition im Mapping
• Fragestellungen
• Wann soll geladen werden? FetchType
• Wie soll geladen werden? FetchMode
www.thoughts-on-java.org
Fetc
h-S
trat
gien
2.1 FetchType
www.thoughts-on-java.org
• 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
Fetc
hTy
pe
• 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-o
ne
mit
Pro
xy
Demo (Projekt EagerLoading)
www.thoughts-on-java.org
2.2 FetchMode
www.thoughts-on-java.org
• 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
Fetc
hM
od
e
Demo (Projekt EagerLoading)
www.thoughts-on-java.org
• 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
Emp
feh
lun
g
2.3 QueryspezifischesFetching
www.thoughts-on-java.org
• Entsteht, wenn lazy Relationen beim Zugriff nachgeladen werden
List<Author> authors = this.em.createQuery("SELECT a FROM Author a",
Author.class).getResultList();
for (Author a : authors) {
System.out.println("Author " + a.getFirstName() + " " + a.getLastName() + " wrote " + a.getBooks().stream().map(b -> b.getTitle()).collect(Collectors.joining(", ")));
}
www.thoughts-on-java.org
N+1
Sel
ects
Demo (Projekt LazyLoading)
www.thoughts-on-java.org
• Besser, benötigte Relationen direkt mit laden:
• (FetchType.EAGER)
• Fetch Join
• @NamedEntityGraph
• EntityGraph
www.thoughts-on-java.org
N+1
Sel
ects
• Verwendung von JOIN FETCH anstatt JOIN in Abfrage
List<Author> authors = this.em.createQuery("SELECT DISTINCT a FROM Author a JOIN FETCH a.books b", Author.class).getResultList();
for (Author a : authors) {
System.out.println("Author " + a.getFirstName() + " " + a.getLastName() + " wrote " + a.getBooks().stream().map(b -> b.getTitle()).collect(Collectors.joining(", ")));
}
www.thoughts-on-java.org
Fetc
hJo
in
Demo (Projekt LazyLoading)
www.thoughts-on-java.org
• 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
Fetc
hJo
in
• Neu in JPA 2.1
• Definiert einen zu ladenden Entitätsgraphen
• @NamedEntityGraph
• @NamedAttributeNode
• @NamedSubGraph
www.thoughts-on-java.org
Nam
edEn
tity
Gra
ph
• 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
Nam
edEn
tity
Gra
ph
Demo (Projekt LazyLoading)
www.thoughts-on-java.org
• Vorteile:
• Queryspezifisches EAGER-loading
• Definition des Graphen unabhängig von der Abfrage
• Nachteile:
• Bildet kartesisches Produkt
www.thoughts-on-java.org
Nam
edEn
tity
Gra
ph
• Neu in JPA 2.1
• Dynamische Variante des @NamedEntityGraph
• Definition mittels Java API
• EntityManager.createEntityGraph(Class entity)
• EntityGraph
• SubGraph
www.thoughts-on-java.org
Enti
tyG
rap
h
Demo (Projekt LazyLoading)
www.thoughts-on-java.org
• 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
Enti
tyG
rap
h
3. Caching
www.thoughts-on-java.org
www.thoughts-on-java.org
DB
2nd Level Cache
1st Level Cache
HibernateSession
QueryCache
1st Level Cache
HibernateSession
Cac
hes
• 1st Level Cache
• An Session gebunden
• Per default aktiviert
• 2nd Level Cache
• Sessionübergreifend
• Konfiguration erforderlich
• Query Cache
• Sessionübergreifend
• Konfiguration erforderlich
www.thoughts-on-java.org
Cac
hes
3.1 1st Level Cache
www.thoughts-on-java.org
• Automatisch aktiviert
• Sessioninterner Speicher verwendeter Entities
• Zugriff erfolgt transparent
www.thoughts-on-java.org
1st
Lev
el C
ach
e
Demo (Projekt 1stLevelCaching)
www.thoughts-on-java.org
3.2 2nd Level Cache
www.thoughts-on-java.org
• 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
2n
d L
evel
Cac
he
• 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
2n
d L
evel
Cac
he
• 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
2n
d L
evel
Cac
he
Demo (Projekt 2ndLevelCaching)
www.thoughts-on-java.org
• 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
2n
d L
evel
Cac
he
• Cache Retrieve Mode
• CacheRetrieveMode.USE (default)
• Daten werden aus Cache gelesen
• CacheRetrieveMode.BYPASS
• Daten werden aus DB gelesen
www.thoughts-on-java.org
2n
d L
evel
Cac
he
• 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
2n
d L
evel
Cac
he
Demo (Projekt 2ndLevelCaching)
www.thoughts-on-java.org
• Concurrency Strategy
• JPA: Definition erfolgt global
• Hibernate: Definition erfolgt spezifisch für jede Entity
• @org.hibernate.annotations.Cache
www.thoughts-on-java.org
2n
d L
evel
Cac
he
• Concurrency Strategy
• Read-only
• Read-write• Nicht für serializable transaction isolation verwendbar
• Nonstrict-read-write• Keine strict transaction isolation
• Transactional• Benötigt JTA• Z.B. Infinispan, EHCache
www.thoughts-on-java.org
2n
d L
evel
Cac
he
3.3 Query Cache
www.thoughts-on-java.org
• 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
Qu
ery
Cac
he
• 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
Qu
ery
Cac
he
Demo (Projekt QueryCaching)
www.thoughts-on-java.org
• 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
Emp
feh
lun
g
• JSR 338: JavaTM Persistence API, Version 2.1 http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index.html
• Hibernate Reference Documentationhttp://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
Qu
elle
n
• 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
Qu
elle
n
Noch Fragen?
www.thoughts-on-java.org
Recommended