Sie sind auf Seite 1von 61

JPA / Hibernate

cd SINGLE_TABLE

Parent SINGLE_TABLE

- attributeP: int column


ID:
DISKRIMINATOR:
ATTRIBUTE_P:
ATTRIBUTE_A:
ATTRIBUTE_B:

ChildA ChildB

- attributeA: int - attributeB: int

Alexander Kunkel
Inhaltsschwerpunkte
• Wissen wird anhand aufeinander aufbauender
praktischer Problemstellungen mit Beispielen aufgebaut.
• Primär JPA, nicht Hibernate proprietär. In Büchern zu
Hibernate wird immer die mächtigere aber proprietäre
API von Hibernate beschrieben.
• Einsatz in JSE nicht JEE.
• Funktionale Aspekte stehen im Vordergrund.
• Kein XML-Mapping, ausschließlich Annotations
• Schrittweise Einführung unter Vermeidung zu vieler
Details.
• Das Thema Konfiguration ist nicht Inhalt.

Alexander Kunkel 11.03.2007 3


Literatur
• „Hibernate und die Java Persistence API“
– Entwickler Press
– Robert Hien, Markus Kehle
• „Java Persistence With Hibernate“
– Manning
– Christian Bauer, Gavin King
• EJB Spezifikation
– http://java.sun.com/products/ejb/docs.html
• Hibernate Dokumentation
– www.hibernate.org

Alexander Kunkel 11.03.2007 4


Legende
• Beispielsourcecode im Package
tst.annotations
tst.annotation

• Hibernate Feature, nicht in JPA


H!

Alexander Kunkel 11.03.2007 5


Inhalt
Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 6


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 7


Arbeitsumgebung HSQLDB
Datenbank HSQL

Starten der
HSQL
Datenbank.

Alexander Kunkel 11.03.2007 8


Arbeitsumgebung Beispiele
Vorbereitete Beispielsourcen

Tabellen zu
Klassen

Diverse Testprogramme

Alexander Kunkel 11.03.2007 9


Arbeitsumgebung Konfiguration für die
Konfiguration DB-Verbindung

Die für die Arbeitsumgebung gewählte Konfigurationsmöglichkeit

Datenbank-Verbindung

Datenbank-dialekt

Statements auf der


Console anzeigen

DB-Schema automatisch
erzeugen

Annotierte Klassen
automatisch finden

Alexander Kunkel 11.03.2007 10


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 11


Java Annotations Was sind
Annotations?

• Metadaten direkt im Sourcecode hinterlegen.


• Diese Metadaten können zur Compilezeit oder zur Laufzeit
ausgelesen werden.
• Annotationen können sich auf folgende Elemente beziehen:
– Packages
– Klassen
– Interfaces
– Enumerations
– Methoden
– Variablen
– Methodenparameter
• Es gibt vordefinierte Annotationen
– @Deprecated
– @Override
– @SuppressWarnings

Alexander Kunkel 11.03.2007 12


Java Annotationen @MissionParameter
Eigene Annotation

SOURCE
CLASS
RUNTIME
• @MissionParameter
– Markieren von Objektvariablen als TYPE
Missionsparameter FIELD
PARAMETER

• MySection CONSTRUCTOR
LOCAL_VARIABLE
ANNOTATION_TYPE
– Vereinfachter Missionsabschnitt PACKAGE

tst.annotation

Alexander Kunkel 11.03.2007 13


Java Annotationen Launcher
Eigene Annotation

Alternativer Launcher, der die Annotation @MissionParameter berücksichtigt

tst.annotation

Alexander Kunkel 11.03.2007 14


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 15


EntityManager
Java Persistence API - Einführung Entity
Beteiligte Komponenten EJB QL, Query-API

• Zugang zu den
Datenbankfunktionalitäten
erhält man mittels dem
EntityManager.
EntityManager
• Es gibt 2 unterschiedliche
Arbeitsweisen.
– Eher objektorientiert mit den
Operationen „store“, „update“,
Objektoperationen EJB QL, Query-API „remove“ und „merge“.
– Eher relational mit der
Datenbanksprache EJB QL
und der Query-API.
Entity • Beide Arbeitsweisen beziehen
sich letztendlich auf
Datenobjekte  Entities und
deren Life-Cycle

Alexander Kunkel 11.03.2007 17


Vergleich
Java Persistence API - Einführung Objektoperationen
Beteiligte Komponenten EJB QL, Query-API

Objektoperationen EJB QL, Query-API

• Entityobjekte stehen im • Datenbanksprache EJB QL


Mittelpunkt der steht im Mittelpunkt der Query-
Datenbankoperationen: API: select, update, delete
persist, remove, merge, find
• Entityobjekte in
• Fortsetzung der Operationen
Abfrageergebnissen.
über Beziehungen hinweg
(Transitive Persistenz)
Cascade
• Ownership

Alexander Kunkel 11.03.2007 18


Java Persistence API - Einführung Entity
Entity

Markieren der Klasse • Benötigt einen


als „Entity“. Defaultkonstruktor.
• Eine Entity-Klasse muss eine
Top-Level-Klasse sein.
• Weder die Klasse noch seine
Attribut „Name“ als Attribute und Methoden dürfen
Primärschlüssel. ‚final‘ sein.
• Die für die Persitenz relevanten
Attribute müssen public Getter-
und Settermethoden gemäß
Attribute werden ohne weitere
der Java-Beans Spezifikation
Angaben automatisch in
haben.
gleichnamige Tabellenspalten • Die Annotationen können
gespeichert. alternativ an den
Objektvariablen oder den
Getter-/Settermethoden notiert
werden. Field-based access,
Property-based access.
• Achtung! Mischen von Field-
based und Property-based
access führt zu Exceptions, die
nicht auf die Ursache schließen
lassen.
• Eine Entity muss einen
Primärschlüssel haben.

tst.firstentity

Alexander Kunkel 11.03.2007 20


Java Persistence API - Einführung Persistenzkontext
EntityManager - Persistenzkontext EntityManager

EntityManager: Methoden, die in den Beispielen verwendet werden

Alexander Kunkel 11.03.2007 22


Java Persistence API - Einführung getTransaction()
EntityManager - Transaktion

• .getTransaction()
– .begin()
– .commit()
– .rollback()
• Leseoperationen können außerhalb einer Transaktion erfolgen.
– .find()
– .getReference()
– .refresh()
• Einige modifizierende Operationen können ebenfalls außerhalb einer Transaktion
gerufen werden. Veränderungen werden in einer Warteschlange zurückgehalten, bis
eine Transaktion eröffnet wird.  !!! Keine Exception
– .persist()
– .merge()
– .remove()
• Einige Operationen können ausschließlich innerhalb einer Transaktion gerufen
werden.  TransactionRequiredException
– .flush()
– .lock()
– Abfragen mit update/delete.

Alexander Kunkel 11.03.2007 23


Java Persistence API - Einführung Session
EntityManager - Transaktion

• Leichtgewichtige Session zur Rahmen für eine Transaktion


Datenbank mit 2 möglichen in einer JSE Umgebung:
Lebensdauern
– STANDARD: Für die Dauer einer
einzigen Transaktion gültig EntityManager em = …
EntityTransaction tx = null;
– EXTENDED: Für die Dauer mehrerer try {
Transaktionen gültig tx = em.getTransaction();
• !!! Nicht threadsafe !!! tx.begin();
// do some work
• Mehrere parallele Transaktionen ...
mittels mehreren parallelen tx.commit();
EntityManagern. }
catch (RuntimeException e) {
• Fehler werden mittels Runtime- if ( tx != null && tx.isActive() )
Exceptions transportiert. tx.rollback();
throw e; // or display error message
• Sobald eine Exception auftritt, muss }
der aktuelle EntityManager verworfen finally {
em.close();
werden. }

Alexander Kunkel 11.03.2007 24


Java Persistence API - Einführung DB-Insert
Entity

Person Insert

Entity-Objekt erzeugen

Entity-Objekt speichern

Hibernate-Log
Hibernate: insert into Person (vorname, name) values (?, ?)

DB

tst.firstentity

Alexander Kunkel 11.03.2007 25


Java Persistence API - Einführung DB-Update
Entity

Person Update

Objekt anhand
Primärschlüssel laden

Setze neuen Vornamen

Objekt wieder
Hibernate-Log speichern

Hibernate: select person0_.name … where person0_.name=?


Hibernate: update Person set vorname=? where name=?

DB

tst.firstentity

Alexander Kunkel 11.03.2007 26


Java Persistence API - Einführung DB-Delete
Entity

Person Delete

Objektreferenz anhand
Primärschlüssel laden

Objekt in DB löschen

Hibernate-Log
Hibernate: select person0_.name … where person0_.name=?
Hibernate: delete from Person where name=?

Select erfolgt, obwohl


DB das Object lediglich
mittels ‚getReference‘
adressiert wird.

tst.firstentity

Alexander Kunkel 11.03.2007 27


Transient
Java Persistence API - Einführung Persistent
Entity - Life-Cycle Detached

Keine Kopie in Mit Kopie in


der Datenbank Operationen der Datenbank
verändern den
Zustand aller
Objekte die sich
im Kontext des Detached
EntityManagers
befinden merge()

load() rollback()
Query.list() commit()
close()
clear()
persist()
new merge()
Transient Persistent
remove()
finalize
Removed persist()
persist()

Alexander Kunkel 11.03.2007 28


Transient
Java Persistence API - Einführung Persistent
Entity - Life-Cycle Detached

Transient (vorübergehend, flüchtig)

Mit ‚new‘ erzeugte Objekte befinden sich lediglich im flüchtigen Arbeitsspeicher. Durch Übergabe an
‚persist‘ des Entity-Managers wechselt der Zustand von ‚Transient‘ zu ‚Persistent‘.
Zu dem Objekt gibt es keinen korrespondierenden Datensatz in der Datenbank.

Persistent (nicht flüchtig)

Mit ‚new‘ erzeugte Objekte befinden sich zunächst lediglich im Arbeitsspeicher. Dieser Zustand wird
als ‚Transient‘ bezeichnet. Durch Übergabe an ‚persist‘ des Entity-Managers wechselt der Zustand zu
‚Persistent‘.

Detached (gelöst)

Vom Persistenzkontext ‚gelöst‘. Im Unterschied zu ‚Transient‘ war das Objekt an sich persistent und
hat noch den Primärschlüssel, zu dem es immer noch einen Datensatz in der Datenbank gibt.

Removed (gelöscht)

Vom Persistenzkontext ‚gelöst‘. Im Unterschied zu ‚Transient‘ war das Objekt an sich persistent und
hat noch den Primärschlüssel, zu dem es immer noch einen Datensatz in der Datenbank gibt.
Alexander Kunkel 11.03.2007 29
Java Persistence API - Einführung Detached
Entity - Life-Cycle merge()

Alexander Kunkel 11.03.2007 30


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 31


@Entity
Java Persistence API @Id
Entity - Primärschlüssel @GeneratedValue
• Eine Entity muss einen Primärschlüssel haben.
• Markieren eines Feldes oder Methode mittels
@Id als Primärschlüssel.
• Nicht zuletzt weil fachliche Schlüssel selten
wirklich eindeutig sind, setzt man in der Regel
auf technische Schlüssel.
• Technische Schlüssel lassen sich einfach mittels
@GeneratedValue generieren.
• Es gibt mehrere Generatorstrategien.
• Zusammengesetzter Primärschlüssel ist mittels
@IdClass möglich, aber ein wenig umständlich
und lediglich für Legacy-Datenbanken relevant.
• Fachlich motivierte Attributkombinationen können
unabhängig vom technischen Schlüssel auf
unique gesetzt werden.

tst.primarykey

Alexander Kunkel 11.03.2007 32


Java Persistence API @GeneratedValue
Entity – Generator für Primärschlüssel

• @GeneratedValue(strategy = ???) legt die Strategie zur


Generierung von Primärschlüsseln fest.
• JPA-Generatorstrategien:
– GenerationType.AUTO – Wählt eine Strategie entsprechend der
zugrunde liegenden Datenbank.
– GenerationType.TABLE – Primärschlüssel werden mittels einer eigenen
Tabelle verwaltet.
– GenerationType.SEQUENCE – Nutzt Sequences wie beispielsweise in
ORACLE.
– GenerationType.IDENTITY – Nutzt spezielle „Identity“ Spalten wie in
MySql, HSQLDB.
• Es gibt noch weitere Hibernate Generatorstrategien
• Es kann auch ein eigener Generator definiert werden.

tst.primarykey

Alexander Kunkel 11.03.2007 33


@Table
Java Persistence API @Column
Entity - Grundlegende Annotationen @Transient

• @Table
– Definiert die primäre Tabelle für
die Entity
– Parameter: name, catalog,
schema, uniqueConstraints
• @Column
– Definiert die Tabellenspalte für
das markierte Feld
– Parameter: name, unique,
nullable, updateable, insertable,
columnDefinition, table, length,
precision, scale
• @Transient
– Markiert ein nicht persistentes
Feld

tst.firstentity

Alexander Kunkel 11.03.2007 34


Java Persistence API @Lob
Entity - Blob

• Benützen von BLOBS und CLOBS


erfolgt unabhängig von der
Datenbank.
• Für Java-Typen:
– Byte[]
– byte[]
– Java.sql.Blob
– String
– Char[]
– char[]
– Java.sql.Clob
• Bei Lobs wird aus dem
Längenconstraint der konkrete
Datenbanktyp abgeleitet. MySql
kennt für einen Blob
unterschiedlich große Typen!

tst.blobs

Alexander Kunkel 11.03.2007 35


Java Persistence API @Temporal
Entity - Datumsfelder

• Annotation kann an java.util.Date


und java.util.Calendar
angebracht werden
• Es gibt 3 Temporaltypen

• Beispiel:

Alexander Kunkel 11.03.2007 36


Java Persistence API
Entity - Fließkommazahlen wie bspw. Geldbeträge

Alexander Kunkel 11.03.2007 37


Not Null
Entity Length
DB-Constraints Unique
Not Null

ORACLE DDL-Skript:
Längenbeschränkung

Unique

Defaultbelegung von Datenbankfeldern

tst.constraints
Foreign Key  Siehe „Beziehungen“
Alexander Kunkel 11.03.2007 38
Hibernate Übersicht
Validatoren H!

Alexander Kunkel 11.03.2007 39


@Size
Hibernate @Range
Validatoren @Email H!

Beispielvalidierungen

Code zur Überprüfung auf Einhaltung der Validierungen

Ergebnis aufgrund schwerer Verfehlungen

Da fehlt noch die


Übersetzung ins
Deutsche ☺
tst.validation

Alexander Kunkel 11.03.2007 40


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 41


Beziehungen Granularität
Paradigmen Missmatch

• Granularität von Objekten unterscheiden sich


cd Impedance Missmatch

von Tabellen. Person Adresse

• Im Beispiel werden die Klassen Person und - name: String - strasse: String

Adresse auf die Tabelle PERSON abgebildet.


0..*

Telefon

- nummer: String

PERSON TELEFON

column column
ID: ID:
NAME: NUMMER:
STRASSE: PERSON_FK:

Alexander Kunkel 11.03.2007 42


1:1 Beziehungen unidirektional Varianten

• Anhand der 1:1 Beziehung lassen sich schon die cd Embedded

meisten Konstrukte demonstrieren. Person Adresse

• 4 Möglichkeiten die 1:1 Beziehung zwischen - name: String


1 0..1
- strasse: String

Person und Adresse zu mappen


– Embedded in eine Tabelle
– Person und Adresse in getrennte Tabellen.
Zusammengehörige Adresse und Person haben
den selben Primärschlüssel.
– Person und Adresse in getrennte Tabellen mit
Foreign Key seitens Person auf Adresse Person
und ggf. einen unique Constraint auf den
Fremdschlüssel.
– Person und Adresse in getrennte Tabellen mit
Foreign Key seitens Adresse auf Person und ggf.
einen unique Constraint auf den Fremdschlüssel.

Alexander Kunkel 11.03.2007 43


1:1 Beziehungen unidirektional @Embedded
Embedded @Embeddable

cd Embedded
Person
Person Adresse

- name: String - strasse: String


1 0..1

PERSON

column
ID: Adresse
NAME:
STRASSE:

Testcode Hibernate-Log
Hibernate: insert into Em_Person (id, name, …
Hibernate: call identity()

tst.one2one.embedded

Alexander Kunkel 11.03.2007 44


1:1 Beziehungen @PrimaryKeyJoinColumn
Shared Primary Key

cd SharedPrimaryKey Person
Person Adresse

- name: String - strasse: String


1 0..1

PERSON ADRESSE

column column
ID: ID:
NAME: STRASSE: Adresse
H!

Testcode Hibernate-Log
Hibernate: insert into SPK_Person (id, name, …
Hibernate: call identity()
Hibernate: insert into SPK_Adresse (id, strasse, …
Hibernate: call identity()

tst.one2one.sharedprimarykey

Alexander Kunkel 11.03.2007 45


1:1 Beziehungen unidirektional @OneToOne
Foreign Key I @JoinColumn

Hier angeben, dass es sich um eine 1:1-Beziehung handelt.


cd ForeignKey
Person
Person Adresse

- name: String - strasse: String


1 0..1

FK_PERSON ADRESSE

column column
ID:
NAME:
ID:
STRASSE: Adresse
FK_ADRESSE:
Optional Spalte für den
Fremdschlüssel angeben.

Testcode Hibernate-Log
Hibernate: insert into Fk_Adresse (id, hausnummer, …
Hibernate: call identity()
Hibernate: insert into Fk_Person (id, name, vorname, …
Hibernate: call identity()

Achtung!
Delete On Cascade in ORACLE
funktioniert hier nicht.

tst.one2one.foreignkey

Alexander Kunkel 11.03.2007 46


1:1 Beziehungen unidirektional @OneToOne
Foreign Key II @JoinColumn

cd ForeignKEy2

Person Adresse

- name: String - strasse: String


1 0..1

PERSON FK_ADRESSE

column column
ID: ID:
NAME: STRASSE:
FK_PERSON:

Dafür habe ich noch kein JPA-Mapping

tst.one2one.foreignkeyreverse

Alexander Kunkel 11.03.2007 47


1:n Beziehungen unidirektional @OneToMany
ohne zusätzlicher Mappingtabelle @JoinColumn

cd One2Many
Hier angeben, dass es sich um
O2m_Person O2m_Telefon
Person eine 1:n-Beziehung handelt.
- id: int - id: int
- name: String 0..* - nummer: String

Telefon
O2M_PERSON O2M_TELEFON

column column
ID: ID:
NAME: NUMMER:
FK_PERSON:

Optional Spalte für den Fremdschlüssel. Ohne


Testcode @JoinColumn wird automatisch eine separate
Tabelle für die Beziehung benützt.

Hibernate-Log
Hibernate: insert into O2m_Person (id, name, ,..
Hibernate: call identity()
Hibernate: insert into O2m_Telefon (bemerkung, …
Hibernate: insert into O2m_Telefon (bemerkung, …
Hibernate: update O2m_Telefon set person_fk=? where nummer=?
Hibernate: update O2m_Telefon set person_fk=? where nummer=?

tst.one2many

Alexander Kunkel 11.03.2007 48


1:n Beziehungen unidirektional @OneToMany
mit zusätzlicher Beziehungstabelle @JoinColumn

cd One2Many
Hier angeben, dass es sich um
O2m_Person O2m_Telefon
Person eine 1:n-Beziehung handelt.
- id: int - id: int

Telefon
- name: String 0..* - nummer: String

O2M_PERSON O2M_TELEFON

column column
ID: ID:
NAME: NUMMER:

O2M_PERSON_O2M_TELEFON

column
O2M_PERSON_ID:
TELEFONNUMMERN_ID:

Testcode Hibernate-Log
Hibernate: insert into O2m_Person (id, name, vorname) values …
Hibernate: call identity()
Hibernate: insert into O2m_Telefon (id, nummer, bemerkung) …
Hibernate: call identity()
Hibernate: insert into O2m_Telefon (id, nummer, bemerkung) …
Hibernate: call identity()
Hibernate: insert into O2m_Person_O2m_Telefon (O2m_Person_id, …
Hibernate: insert into O2m_Person_O2m_Telefon (O2m_Person_id, …

tst.one2many

Alexander Kunkel 11.03.2007 49


Lazy vs. Eager Loading

• Strategie bzgl. dem Laden referenzierter Daten


– Eager: Gleich alles mitladen.
– Lazy: Erst dann laden, wenn ein Zugriff darauf erfolgt.
• Achtung!
– Gemäß EJB3 Spezifikation ist derzeit Lazy-Loading optional.
– Lazy-Loading führt bei Hibernate zu Proxy-Objekten.
Probleme mit Objektidentitäten möglich.
– Lazy-Loading mit Detached Entities führt zu Exceptions.
– Die „Tiefe“ des Mitladens ist beschränkt, aber einstellbar.
– Eager-Loading wirkt nicht bei Queries
• Relevante Stellen
– Annotation bei Objektattributen und Beziehungen
– Fetchstrategie bei Abfragen
• Defaults
– Eager bei Objektattributen
– Lazy bei ?:n Beziehungen

Alexander Kunkel 11.03.2007 50


Lazy vs. Eager Loading @Basic
Beispiele @OneToMany

Person
Abändern der Strategie
bei Attributen von
EAGER auf LAZY

Abändern der Strategie


bei einer 1:n Beziehung
von LAZY auf EAGER

SQL bei LAZY SQL bei EAGER

tst.lazyeager

Alexander Kunkel 11.03.2007 51


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 52


Datenabfragen .find(…)
Via EntityManager .getReference(…)

.find(…)

Hibernate-Log
### Anhand Primärschlüssel vollständig laden
Hibernate: select q_person0_.id as id11_1_, q_person0_.name as name11_1_, …

.getReference(…)

Hibernate-Log Man beachte, dass der Select


erst bei Zugriff auf ein Attribut
### Anhand Primärschlüssel Referenz laden stattfindet
## Zugriff auf 'name'
Hibernate: select q_person0_.id as id11_1_, q_person0_.name as name11_1_, …

tst.query

Alexander Kunkel 11.03.2007 53


Datenabfragen Select
QL-API, QL-Language Left join fetch

Einfacher Select

Hibernate-Log Man beachte, dass trotz Eager-


Loading 2 Selects ausgeführt
### Einfacher Select werden
Hibernate: select q_person0_.id as id11_, q_person0_.name as name11_, …
Hibernate: select telefonnum0_.person_fk as person3_1_, …

Fetch Join

Hibernate-Log
### Einfacher Select als FETCH JOIN
Hibernate: select q_person0_.id as id11_0_, telefonnum1_.nummer as nummer12_1_, …

tst.query

Alexander Kunkel 11.03.2007 54


Datenabfragen Select Count
Select Count, Paginierung Paginierung

Select Count

Hibernate-Log
### Select count
Hibernate: select count(q_telefon0_.nummer) as col_0_0_ from Q_Telefon q_telefon0_ where q_telefon0_.nummer like ?
## count=5

Paginierung

Hibernate-Log
### Paginierung
Hibernate: select top ? q_telefon0_.nummer as nummer12_, q_telefon0_.bemerkung as …
## count=3
Hibernate: select limit ? ? q_telefon0_.nummer as nummer12_, q_telefon0_.bemerkung as … tst.query
## count=2

Alexander Kunkel 11.03.2007 55


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 56


Optimistisches Locking @Version

Person
Zusätzliches Attribut, um
Information zur Objektversion
• Für @Version können folgende
aufzunehmen. Typen eingesetzt werden:
– int, Integer
– short, Short
Testcode – long, Long
– Timestamp

Hibernate-Log
insert into L_Person (id, version, name) values …
call identity()
select l_person0_.id as id7_0_, l_person0_.version as …
select l_person0_.id as id7_0_, l_person0_.version as …
update L_Person set version=?, name=? where version=? …
update L_Person set version=?, name=? where version=? …
… Row was updated or deleted by another transaction

javax.persistence.RollbackException
caused by … tst.locking
javax.persistence.OptimisticLockException

Alexander Kunkel 11.03.2007 57


Pessimistisches Locking

Alexander Kunkel 11.03.2007 58


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 59


Sortieren
Sortierung seitens der DB

• @OrderBy(value=„nummer DESC“
• Order by in der Query mit fetch join

• Sortierung des Ergebniscollection im


Speicher
• Sortierung der Ergebniscollection
seitens der DB
• Sortierung in einer Query  Abfrage
nach Person sortieren
• Sortierung an der Beziehung
spezifizieren  Sort-Annotation,
SortedMap

Alexander Kunkel 11.03.2007 60


Arbeitsumgebung
Java-Annotations
Java Persistence API Einführung
Entity
Beziehungen
Vererbung
Datenabfragen
Sortieren
Caching
Sperrstrategien

Alexander Kunkel 11.03.2007 61


Vererbung SINGLE_TABLE
SINGLE_TABLE

• Eine Tabelle pro Objekthierarchie cd SINGLE_TABLE

SINGLE_TABLE
• Vorteile
Parent

- attributeP: int column


ID:
– Performanteste Variante. DISKRIMINATOR:
ATTRIBUTE_P:
– Einfach umzusetzen. ATTRIBUTE_A:
ATTRIBUTE_B:

– Polymorphe Suche ist automatisch ChildA ChildB

gegeben. - attributeA: int - attributeB: int

– Es werden keine Joins benötigt.


• Nachteile
– Platzverschwendung, da nicht alle
Attribute für jeden Typ relevant sind.
– Bei Einführung eines neuen Subtyps
muss die Tabelle angepasst werden.

Alexander Kunkel 11.03.2007 62


Vererbung JOINED
JOINED

• Eine Tabelle für jede Klasse. cd JOINED

• Vererbung wird als 1:1 Parent PARENT


Die 1:1 Beziehung zwischen

Beziehung zwischen den - attributeP: int column


ID:
PARENT und CHILD_? wird
mittels gleichen Primary-Keys
Tabellen abgebildet. DISCRIMINATOR:
ATTRIBUTE_P:
bewerkstelligt.

• Vorteile
– Klassen werden eins zu eins
abgebildet. ChildA ChildB CHILD_A CHILD_B

– Platz wird nicht verschwendet. - attributeA: int - attributeB: int column column
ID: ID:
– Bei Einführung eines neuen ATTRIBUTE_A: ATTRIBUTE_B:

Subtyps müssen bestehende


Tabellen nicht geändert
werden.
• Nachteile
– Bereits bei einer Suche nach
einer konkreten Klasse muss
ein Join verwendet werden.
– Polymorphe Abfragen sind
komplex.

Alexander Kunkel 11.03.2007 63


Vererbung TABLE_PER_CLASS
TABLE_PER_CLASS

• Eine Tabelle für jede konkrete cd TABLE_PER_CLASS

Klasse Parent CHILD_A CHILD_B

column column
• Diese Strategie ist lt. EJB 3.0
- attributeP: int
ID: ID:
ATTRIBUTE_P: ATTRIBUTE_P:
optional. ATTRIBUTE_A: ATTRIBUTE_B:

• Vorteile
– Für die Suche nach konkreten
ChildA ChildB

- attributeA: int - attributeB: int


Typen werden keine Joins
benötigt.
• Nachteile
– Gemeinsame Attribute von
Basistypen sind redundant.
– Pflege der Tabellen aufwendig.
– Polymorphe Abfragen sind
aufwendig. Mehrere Selects oder
Union.

Alexander Kunkel 11.03.2007 64


Ratschläge & Fallen

• Schwierigkeit, wie viele Festlegungen schon im Datenmodell definiert werden, ohne das
Datenmodell in seiner Universalität zu sehr einzuschränken.
• Zunächst davon ausgehen, dass alle Beziehungen Lazy geladen werden und Bedarf mit Join-
Fetches Eager geladen werden. Im Einzelfall mit Begründung von der Strategie abweichen.
• O/R-Mapper bringt einige Erleichterungen. Allerdings verlagert sich die Komplexität auf die
angemessene Anwendung der zahlreichen Möglichkeiten. Es ist also kein Ersatz für fehlende
Kenntnisse.
• Als Datenattribute ausschließlich Objekte verwenden, damit der Zustand „NULL“ abfragbar wird.
Auch wenn es den Anschein hat, dass primitive Datentypen ausreichend wären, wird man früher
oder später mit der „NULL“ Problematik konfrontiert werden.
• Bei Lobs wird aus dem Längenconstraint der konkrete Datenbanktyp abgeleitet. Bei MySql gibt es
für einen Blob unterschiedlich große Typen!
• Das Design des Objektmodells soll trotz den Möglichkeiten des O/R-Mappers flach sein. Eine
filigrane Objektstruktur über viele Ebenen hinweg ist nach wie vor schwer zu beherrschen.
• Achtung! Mischen von Field-based und Property-based access führt zu Exceptions, die nicht auf
die Ursache schließen lassen.
• Wie bei der Datenmodellierung üblich sollten auch beim O/R-Mapping alle Feldlängen explizit
angegeben werden.

Alexander Kunkel 11.03.2007 65