Sie sind auf Seite 1von 49

 

635-0.book Seite 1 Montag, 6. August 2007 12:52 12

Sebastian Hennebrüder

Hibernate
Das Praxisbuch für Entwickler
635-0.book Seite 3 Montag, 6. August 2007 12:52 12

Auf einen Blick

1 Einführung in Hibernate .................................................. 17

2 Fortgeschrittene Techniken ........................................... 73

3 Konfiguration .................................................................... 143

4 Mapping-Beispiele ........................................................... 167

5 Integration anderer Technologien ................................ 285

6 JPA und EJB 3 .................................................................... 301

A Annotation Reference ...................................................... 319

B Hilfreiche Tools ................................................................. 357

C Literaturverzeichnis .......................................................... 359


635-0.book Seite 5 Montag, 6. August 2007 12:52 12

Inhalt

Vorwort ........................................................................................................ 11
Warum Hibernate? ................................................................................. 11
Ziel des Buches ...................................................................................... 12
Wofür braucht man Hibernate? .............................................................. 13
Aufbau des Buches ................................................................................. 14
Hibernate Version .................................................................................. 15

1 Einführung in Hibernate ........................................................... 17


1.1 Erstes Hibernate-Beispiel ............................................................. 17
1.1.1 Projekt und Klassen erstellen .......................................... 18
1.1.2 Hibernate-Konfiguration ................................................. 21
1.1.3 Mapping ......................................................................... 23
1.1.4 Notwendige Bibliotheken ................................................ 27
1.1.5 Session-Factory erstellen ................................................. 28
1.1.6 Logging Konfiguration ..................................................... 29
1.1.7 Datenbank und Tabellen erstellen ................................... 29
1.1.8 Testen ............................................................................. 30
1.1.9 MyEclipse Tools für die Hibernate-Entwicklung ............... 34
1.1.10 Andere Tools für die Hibernate-Entwicklung ................... 37
1.2 Hibernate-Grundlagen ................................................................. 37
1.2.1 Leistungsfähige Mapping-Varianten ................................ 37
1.2.2 Leistungsfähige Abfragesprachen ..................................... 38
1.2.3 Architektur ...................................................................... 39
1.2.4 Lazy Initialization, ein Problembereich ............................ 40
1.2.5 Drei Status von Objekten ................................................ 44
1.2.6 Zusammenfassung ........................................................... 46
1.3 Mit Objekten arbeiten ................................................................. 47
1.3.1 Speichern ........................................................................ 47
1.3.2 Ändern ............................................................................ 48
1.3.3 Löschen .......................................................................... 53
1.3.4 Weitere Befehle .............................................................. 55
1.4 Ein komplexeres Beispiel – eine Webanwendung ......................... 56
1.4.1 Analyse der Anforderungen ............................................. 56
1.4.2 Webprojekt erstellen ....................................................... 58
1.4.3 Klassen erstellen ............................................................. 58
1.4.4 Hibernate-Konfiguration ................................................. 61
1.4.5 Mapping der Vererbungsklassen ...................................... 61

5
635-0.book Seite 6 Montag, 6. August 2007 12:52 12

Inhalt

1.4.6 Mapping der Beziehungen .............................................. 63


1.4.7 Anwendungslogik ........................................................... 65
1.4.8 Webanwendung .............................................................. 67

2 Fortgeschrittene Techniken ..................................................... 73


2.1 Zeit zum Springen ........................................................................ 73
2.2 Best Practices und DAO ............................................................... 74
2.2.1 Data Access Objects (DAO) ............................................. 74
2.2.2 Anwendungsfall Buchversand .......................................... 75
2.2.3 Transaktionssteuerung ..................................................... 76
2.2.4 DAO Factory ................................................................... 77
2.2.5 Problem der Wiederverwendung von Geschäftslogik ....... 79
2.2.6 DAOs mit Generics .......................................................... 81
2.2.7 DAOs mit Java 1.4 .......................................................... 84
2.2.8 Kluge DAOs .................................................................... 86
2.3 Session und Transaktionen ........................................................... 87
2.3.1 Hintergrundwissen zu Sessions ........................................ 87
2.3.2 JTA versus JDBC-Transaktionen ....................................... 88
2.3.3 Konversationen und Session-Lebensdauer ....................... 94
2.3.4 Konkurrierender Zugriff ................................................... 100
2.4 Daten abfragen ............................................................................ 103
2.4.1 Vergleich von HQL, Criteria und SQL .............................. 103
2.4.2 Abfragen mit HQL und Criteria ........................................ 105
2.4.3 Where-Bedingungen ....................................................... 109
2.4.4 SQL-basierte Abfragen .................................................... 114
2.5 Performance ................................................................................ 115
2.5.1 Einleitung ....................................................................... 115
2.5.2 Debugging der Abfragen ................................................. 115
2.5.3 Effizientes Iterieren durch Beziehungen ........................... 117
2.5.4 Effiziente Abfragen bei Beziehungen ............................... 118
2.5.5 Separate Klassen für Berichte .......................................... 118
2.5.6 Verwendung des Caches ................................................. 119
2.5.7 Read-Only-Mapping ....................................................... 120
2.5.8 Verzicht auf Beziehungen ................................................ 120
2.5.9 Iterieren durch große Datenmengen ................................ 121
2.5.10 Schreiben von großen Datenmengen ............................... 122
2.5.11 Verwendung von Stored Procedures ................................ 125
2.5.12 Lazy Loading für Attribute ............................................... 125
2.6 Fortgeschrittene Möglichkeiten ................................................... 126
2.6.1 Bytecode-Instrumentation ............................................... 126

6
635-0.book Seite 7 Montag, 6. August 2007 12:52 12

Inhalt

2.6.2 Named Queries ............................................................... 128


2.6.3 Dynamic-update, dynamic insert ..................................... 129
2.6.4 Eigene Types definieren .................................................. 130
2.6.5 Eigene Entity-Persister erstellen ...................................... 130
2.6.6 Interceptor ...................................................................... 131
2.6.7 Events ............................................................................. 132
2.6.8 Mapping auf XML statt Klassen ....................................... 133
2.6.9 Validieren von Attributen ................................................ 133
2.6.10 Volltextindizierung mit Lucene ........................................ 134
2.6.11 LOB mit Oracle und PostgreSQL ..................................... 134

3 Konfiguration ........................................................................... 143


3.1 Einstellungen ............................................................................... 143
3.1.1 Konfiguration mit Java .................................................... 144
3.1.2 Datenbankverbindung ..................................................... 144
3.1.3 Session- und Transaktionsverhalten ................................. 147
3.1.4 JDBC-Einstellungen ......................................................... 148
3.1.5 Cache-Einstellungen ........................................................ 149
3.1.6 Weitere Einstellungen ..................................................... 150
3.2 Connection Pool .......................................................................... 152
3.2.1 Hibernate Connection Pool ............................................. 152
3.2.2 C3P0 ............................................................................... 153
3.2.3 DBCP .............................................................................. 153
3.2.4 JNDI ............................................................................... 154
3.3 Caches ......................................................................................... 157
3.3.1 Einleitung ....................................................................... 157
3.3.2 Einsatz des Caches .......................................................... 160
3.3.3 Einsatz des Query Caches ................................................ 162
3.3.4 Testen der Cache-Implementierungen ............................. 163
3.3.5 Wie viel Performance bringt ein Cache? .......................... 164
3.3.6 EH Cache ........................................................................ 164
3.3.7 OS Cache ........................................................................ 165
3.3.8 Swarm Cache .................................................................. 165
3.3.9 JBoss TreeCache .............................................................. 166

4 Mapping-Beispiele ................................................................... 167


4.1 Mapping mit Annotation oder XML ............................................. 167
4.2 Annotation Mapping ................................................................... 169
4.2.1 Was sind Annotations? .................................................... 169

7
635-0.book Seite 8 Montag, 6. August 2007 12:52 12

Inhalt

4.2.2 Felder-, Methoden- und Klassen-Annotations ................. 170


4.2.3 Voraussetzungen ............................................................. 171
4.2.4 Weitere Informationen .................................................... 171
4.3 XML Mapping ............................................................................. 171
4.3.1 Übersicht ........................................................................ 171
4.3.2 Class Mapping ................................................................. 173
4.3.3 Weitere XML Tags ........................................................... 176
4.4 Mapping von Primärschlüsseln ..................................................... 176
4.4.1 Natürliche versus künstliche Ids ...................................... 177
4.4.2 Quellcode ....................................................................... 178
4.4.3 Id-Strategie Assigned ...................................................... 178
4.4.4 Id-Strategie automatisch ................................................. 179
4.4.5 Weitere Annotation-Id-Strategien ................................... 179
4.4.6 XML-Id-Strategien .......................................................... 180
4.4.7 Composite Id .................................................................. 183
4.5 Mapping von Beziehungen .......................................................... 187
4.5.1 Einführung ...................................................................... 187
4.5.2 List, Set, Map oder Array ................................................. 188
4.5.3 Uni- und bidirektionale Beziehungen .............................. 204
4.5.4 Cascading ........................................................................ 207
4.5.5 Hinweise zu den Beispielen ............................................. 209
4.5.6 1:1 Beziehung ................................................................. 210
4.5.7 1:n-Beziehung ................................................................. 216
4.5.8 m:n-Beziehung ................................................................ 227
4.5.9 1:n:1-Beziehung .............................................................. 233
4.5.10 Rekursive Beziehung ....................................................... 236
4.5.11 Typisierte Beziehung (XML) ............................................. 238
4.5.12 Typisierte Beziehung (Annotation Workaround) .............. 241
4.6 Mapping von Komponenten ........................................................ 243
4.6.1 Einführung ...................................................................... 243
4.6.2 Eine Komponente ........................................................... 244
4.6.3 Eine Liste von Komponenten ........................................... 247
4.6.4 Ein Set von Komponenten ............................................... 249
4.6.5 1:n:1-Komponente .......................................................... 251
4.6.6 Zusammengesetzte Primärschlüssel als Komponente ....... 254
4.7 Vererbung ................................................................................... 257
4.7.1 Einführung ...................................................................... 257
4.7.2 Auswahl des Mapping-Ansatzes ...................................... 259
4.7.3 Klassenhierarchie in einer Tabelle .................................... 262
4.7.4 Klassenhierarchie mit einer Tabelle pro Klasse ................. 266

8
635-0.book Seite 9 Montag, 6. August 2007 12:52 12

Inhalt

4.7.5 Klassenhierarchie mit einer Tabelle pro Klasse und


Discriminator .................................................................. 271
4.7.6 Vermischen zweier Ansätze ............................................. 274
4.7.7 Klassenhierarchie mit einer Tabelle für jede
konkrete Klasse ............................................................... 274
4.7.8 Klassenhierarchie mit einer Tabelle pro Unterklasse ......... 279
4.7.9 Klassenhierarchie mit einer Tabelle pro Unterklasse ......... 281
4.8 Weitere Mappings ....................................................................... 284

5 Integration anderer Technologien ........................................... 285


5.1 Hibernate und Spring ................................................................... 285
5.1.1 Konfiguration .................................................................. 285
5.1.2 Verwendung des Spring Templates .................................. 288
5.1.3 Alternative zum Spring Template ..................................... 290
5.1.4 Transaktionssteuerung ..................................................... 291
5.2 Hibernate und Struts .................................................................... 293
5.2.1 Optimistisches Sperren .................................................... 293
5.2.2 Zentrales Exception Handling .......................................... 294
5.3 Hibernate und JSF/MyFaces ......................................................... 295
5.3.1 Implementierung ............................................................ 295
5.3.2 Zentrales Exception Handling .......................................... 296
5.4 Integration in JBoss mit Hibernate Service Bean ........................... 297

6 JPA und EJB 3 ........................................................................... 301


6.1 JPA Beispiel ohne EJB Container .................................................. 302
6.1.1 Persistenz-Provider ......................................................... 302
6.1.2 Gemappte Klassen .......................................................... 303
6.1.3 Mit Objekten arbeiten .................................................... 303
6.1.4 Hibernate in JPA nutzen .................................................. 305
6.1.5 Exception Handling ......................................................... 305
6.2 Unterschiede zwischen Hibernate und JPA ................................... 307
6.3 EJB 3 ........................................................................................... 307
6.3.1 Deployment nach Glassfish ............................................. 310
6.3.2 Deployment nach JBoss ................................................... 311
6.4 Dialoge mit lang lebender Session ............................................... 313

9
635-0.book Seite 10 Montag, 6. August 2007 12:52 12

Inhalt

Anhang............................................................................................ 317
A Annotation Reference ............................................................................ 319
A.1 Annotations für Entities und Tabellen .......................................... 319
A.2 Annotations für Primärschlüssel ................................................... 324
A.3 Annotations für Spalten ............................................................... 327
A.4 Annotations für Beziehungen ....................................................... 331
A.5 Annotations für Komponenten .................................................... 333
A.6 Annotations für Beziehung und Komponenten ............................. 335
A.7 Annotations für Vererbung .......................................................... 343
A.8 Sonstige Annotations ................................................................... 345
A.9 Annotation für benannte Filter ..................................................... 348
A.10 Annotation für HQL Queries ........................................................ 350
A.11 Annotation für SQL Queries ......................................................... 352
B Hilfreiche Tools ...................................................................................... 357
C Literaturverzeichnis ................................................................................ 359

Index ............................................................................................................ 361

10
635-0.book Seite 17 Montag, 6. August 2007 12:52 12

Wir starten mit einem Beispiel, in dem wir eine Anwendung für ein
Datenbank konfigurieren, Daten erzeugen, löschen und abfragen und das
objektorientierte Konzept der Assoziation verwenden. Danach werden wir
uns die Bausteine und drei unterschiedliche Status von Hibernate ansehen,
bevor es um das Speichern, Bearbeiten, Löschen und Ändern von Objekten
geht. Am Ende des Kapitels erstellen wir dann bereits die erste Webanwen-
dung.

1 Einführung in Hibernate

Für jede richtige Anwendung benötigt man einen Anwendungsfall. Daher starten
wir mit einem ersten Beispiel.

1.1 Erstes Hibernate-Beispiel


Unser Anwendungsfall ist süß. Wir untersuchen die Honigproduktion. Bekann-
termaßen benötigen wir viele Bienen, um ein Glas Honig zu erzeugen. Um das
darzustellen, sind zwei Klassen erforderlich: Honig (engl. honey) und Biene (engl.
bee).

Bienen und Honig stehen in einer 1:n-Beziehung oder – wenn wir eine objekto-
rientierte Terminologie verwenden möchten – es gibt eine 1:n-Assoziation zwi-
schen der Klasse Biene und Honig. Folgende Abbildung zeigt uns das entspre-
chende Klassendiagramm.

Honey honey 1 Bee


-id : Integer -id : Integer
-name : String -name : String
-taste : String -honey : Honey
-bees : Bee = new HashSet<Bee>() bees *

Abbildung 1.1 Ein Klassendiagramm

Die beiden Objekte werden wir in den unten gezeigten Tabellen in der Daten-
bank speichern:

17
635-0.book Seite 18 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

honey bee
+ id int4 Nullable = false + id int4 Nullable = false
name varchar(255) Nullable = true name varchar(255) Nullable = true
taste varchar(255) Nullable = true # honey_id int4 Nullable = true

Abbildung 1.2 Tabellen in Hibernate

Damit wir eine vollständige Hibernate-Anwendung erhalten, müssen wir meh-


rere Schritte unternehmen:

왘 Klassen erstellen
왘 Mapping zu den Datenbanktabellen festlegen, in denen Honig und Biene
gespeichert werden
왘 Hibernate-Libraries konfigurieren
왘 Hibernate konfigurieren mitsamt Datenquelle
왘 Quellcode schreiben, der unsere Klassen verwendet

Quellcode
Für dieses Beispiel finden Sie den gesamten Quellcode im Buch und auf der Webseite
zum Buch: http://www.galileocomputing.de/978. Für alle anderen Beispiele werden
im Buch nur Ausschnitte gezeigt. Das Projekt heißt FirstHibernateExample bzw. First-
AnnotationExample für die Annotation-Variante.

1.1.1 Projekt und Klassen erstellen

Java-Projekt erstellen
Erstellen Sie in Ihrer Entwicklungsumgebung ein neues Java-Projekt. Ich habe
Eclipse verwendet, aber es gibt natürlich auch sehr gute andere IDEs.

Ich habe das Projekt FirstHibernateExample genannt.

Klassen erstellen
Wir benötigen eine Klasse mit Namen Honey im Package de.laliluna.example.
Unsere Klasse hat vier Attribute:

Integer id – eine Zahl als Primärschlüssel

String name – Name des Honigs

String taste – Beschreibung des Geschmacks

java.util.Set<Bee> bees – Bienen, die den Honig erzeugt haben

18
635-0.book Seite 19 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

Ferner brauchen wir:

왘 die Getter und Setter für unsere Attribute. Diese kann man in Eclipse im Kon-
textmenü 폷 Source 폷 Generate Getter and Setter erzeugen.
왘 einen parameterlosen Konstruktor
왘 die Implementierung von Serializable
왘 eine toString-Methode. Diese verwenden wir für Debug-Ausgaben.

So sollte der Quellcode aussehen:

package de.laliluna.example;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Set;
public class Honey implements Serializable {
private Integer id;
private String name;
private String taste;
private Set<Bee> bees = new HashSet<Bee>();
public Honey() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTaste() {
return taste;
}
public void setTaste(String taste) {
this.taste = taste;
}
public Set<Bee> getBees() {
return bees;
}
public void setBees(Set<Bee> bees) {

19
635-0.book Seite 20 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

this.bees = bees;
}
public String toString() {
return MessageFormat.format("Honey: {0} {1} {2}",
new Object[]{id, name, taste});
}
}

Bitte nicht vergessen


Damit eine gemappte Klasse korrekt funktioniert, denken Sie bitte immer an die fol-
genden Punkte:
왘 Serializable implementieren
왘 Konstruktor ohne Parameter (Defaultkonstruktor)
왘 eine ordentliche toString-Methode

Hinweis zur Java-Version


Ich habe Java Generics verwendet, die mit Java Version 5 eingeführt worden sind.
Wenn Sie Java 1.4 nutzen müssen, löschen Sie Dinge wie <Bee> und die Annotation,
die es manchmal gibt.
Annotations beginnen mit @.

Jetzt müssen wir die Klasse Bienen (Bee) mit folgenden Attributen erstellen:

왘 Integer id
왘 String name
왘 Honey honey

Das Attribut id ist wiederum der Primärschlüssel und die anderen Attribute sind
Merkmale der Klasse.

Hier gilt der gleiche »Bitte nicht vergessen«-Hinweis, den ich bei der vorherigen
Klasse gegeben habe.

Unsere Klasse:

package de.laliluna.example;
import java.io.Serializable;
import java.text.MessageFormat;
public class Bee implements Serializable {
private Integer id;
private String name;
private Honey honey;
public Bee() {
}

20
635-0.book Seite 21 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

public Bee(String name) {


this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Honey getHoney() {
return honey;
}
public void setHoney(Honey honey) {
this.honey = honey;
}
public String toString() {
return MessageFormat.format("{0}: id={1}, name={2}",
new Object[] { getClass().getSimpleName(), id, name }); }
}

1.1.2 Hibernate-Konfiguration
In der Konfiguration legen wir folgende Dinge fest:

왘 die Datenbank, mit der wir uns verbinden


왘 den Typ der Datenbank (MySQL, PostgreSQL, Oracle ...)
왘 die Konfigurationseinstellungen für Hibernate
왘 die Klassen bzw. XML Mappings, die eingelesen werden

Legen Sie bitte eine Datei hibernate.cfg.xml im src-Verzeichnis an. Und jetzt die
große Frage:

Annotation oder XML Mapping?


Wir haben zwei Möglichkeiten, das Mapping der Klassen auf Tabellen festzulegen:
Annotation und XML. Ich diskutiere die Unterschiede in Abschnitt 4.1, »Mapping mit
Annotation oder XML«, im Detail. Hier treffen wir einfach eine schnelle Entschei-
dung.

21
635-0.book Seite 22 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

Wenn Sie Java 5 oder neuer verwenden, empfehle ich, Annotations zu verwenden,
wenn nicht, haben Sie keine andere Wahl als XML.

Ich zeige Ihnen jetzt eine Annotation-Version für PostgreSQL und gebe dann die
Hinweise, was man ändern muss, um die Konfiguration für andere Datenbanken
oder XML Mappings anzupassen.

<?xml version='1.0' encoding='UTF-8'?>


<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-
3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">
jdbc:postgresql://localhost:5432/learninghibernate
</property>
<property name="connection.username">postgres</property>
<property name="connection.password">p</property>
<property name="connection.driver_class">
org.postgresql.Driver
</property>
<property name="dialect">
org.hibernate.dialect.PostgreSQLDialect
</property>
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<property name="current_session_context_class">thread
</property>
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.JDBCTransactionFactory
</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping class="de.laliluna.example.Honey" />
<mapping class="de.laliluna.example.Bee" />
</session-factory>
</hibernate-configuration>

Die Konfiguration enthält zu Beginn die Datenbankverbindung. Anschließend


legen wir mit der Einstellung dialect fest, in welchen SQL-Dialekt Hibernate
Abfragen übersetzt.

Dann konfigurieren wir den Cache und wie sich die Session verhalten soll.
hbm2ddl.auto stellt sicher, dass Hibernate unsere Tabellen erstellt.

22
635-0.book Seite 23 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

Schließlich legen wir fest, welche Mappings gelesen werden. Wenn wir Annota-
tions verwenden, referenzieren wir die Klassen mit <mapping class>.

Andere Datenbanken
Eine Konfiguration für MySQL benötigt folgende Anpassungen:

<property name="connection.url">
jdbc:mysql://localhost/learninghibernate
</property>
<property name="connection.username">root</property>
<property name="connection.password">r</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>

Wenn Sie eine andere Datenbank verwenden möchten, müssen Sie die Einstel-
lung connection.url und dialect anpassen. Werfen Sie einen Blick in das Java-
Package org.hibernate.dialect der hibernate.jar. Diese finden Sie im Download
von Hibernate. Dort finden Sie alle existierenden Dialekte.

Hier ein Auszug aus den unterstützten Dialekten: MySQL5Dialect, OracleDialect,


SybaseDialect, SQLServerDialect, HSQLDialect, DerbyDialect.

Die connection.url entspricht der URL einer normalen JDBC-Verbindung.

XML Mapping statt Annotation


Das XML Mapping erfolgt in XML-Dateien. Wir müssen nur eine kleine Ände-
rung an der Konfiguration vornehmen, und zwar die beiden <mapping>-Tags
ersetzen.

<mapping resource="de/laliluna/example/Honey.hbm.xml" />


<mapping resource="de/laliluna/example/Bee.hbm.xml" />

1.1.3 Mapping
Mit dem Mapping legen wir fest, welcher Tabelle und welcher Spalte ein Attribut
einer Klasse zugeordnet ist. Wie oben bereits erwähnt, gibt es zwei Möglichkei-
ten: Annotation und XML.

23
635-0.book Seite 24 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

Annotation Mapping
Eine Annotation ist immer an dem @ zu erkennen. Damit können wir im Quell-
code Hinweise geben. Fügen Sie einfach die folgenden Annotations hinzu.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
@Entity
@SequenceGenerator(name = "honey_seq", sequenceName =
"honey_id_seq")
public class Honey implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,
generator="honey_seq")
private Integer id;
private String name;
private String taste;
@OneToMany(mappedBy="honey")
private Set<Bee> bees = new HashSet<Bee>();

Mit der Annotation @Entity wird bestimmt, dass unsere Klasse gemappt ist. Den
Primärschlüssel kennzeichnen wir mit @Id. Unser Primärschlüssel verwendet
eine Datenbanksequenz. Diese muss mit Hilfe von @SequenceGenerator definiert
werden, bevor wir beim Attribut id festlegen können, dass es von diesem »Gene-
rator« erzeugt wird (@GeneratedValue).

Die Annotation @OneToMany beschreibt, dass unser Attribut bees in einer 1:n-
Beziehung zur Klasse Bee steht. Ich möchte die genaue Festlegung der Fremd-
schlüsselbeziehung zwischen den Tabellen in der Klasse Bee vornehmen. Daher
habe ich den Parameter mappedBy verwendet.

Die Klasse Bee hat zwei weitere Annotations. @ManyToOne beschreibt die Bezie-
hung aus Sicht der Klasse Bee. Mit der Annotation @JoinColumn legen wir fest,
dass in der Tabelle bee eine Fremdschlüsselspalte existiert. Da wir keinen Namen
festlegen, verwendet Hibernate die Spalte honey_id.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

24
635-0.book Seite 25 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

import javax.persistence.SequenceGenerator;
@Entity
public class Bee implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "bee_gen")
@SequenceGenerator(name = "bee_gen", sequenceName = "bee_id_seq")
private Integer id;
private String name;
@ManyToOne
@JoinColumn
private Honey honey;

Andere Datenbanken
Nicht alle Datenbanken unterstützen Sequenzen, um Werte für den Primär-
schlüssel zu erzeugen. Für die meisten Datenbanken sollte aber folgende Annota-
tion funktionieren:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;

Sie wählt einen Generator abhängig vom konfigurierten Datenbank-Dialekt.

XML Mapping
Sie benötigen XML Mappings nur, wenn Sie keine Annotations verwenden.

In der Mapping-Datei wird die Zuordnung zwischen Attributen und Daten-


bankspalten festgelegt. Legen Sie die Datei Honey.hbm.xml im Package de.lali-
luna.example an.

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping
DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-
3.0.dtd" >
<hibernate-mapping package="de.laliluna.example">
<class name="Honey" table="thoney" >
<id name="id" column="id">
<generator class="sequence">
<param name="sequence">honey_id_seq</param>
</generator>
</id>
<property name="name" type="string"></property>
<property name="taste" type="string"></property>

25
635-0.book Seite 26 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

<set name="bees" inverse="true">


<key column="honey_id"></key>
<one-to-many class="Honey" />
</set>
</class>
</hibernate-mapping>

Mit <id> wird der Primärschlüssel beschrieben und wie dieser erzeugt wird. Die
»normalen« Attribute werden mit Hilfe von <property> den Tabellenspalten
zugeordnet. Wenn wir keinen Namen für die Tabellenspalte angeben
(column=«xyz«), wird der Name des Attributs übernommen.

<set> beschreibt die Beziehung zur Klasse Bee.

Da wiederum nicht alle Datenbanken Sequenzen unterstützen, können wir


Hibernate anhand des Datenbankdialekts einen Generator auswählen lassen.
Ändern Sie das Tag für den Generator wie folgt:

<generator class="native"/>

Wenn auch das nicht funktioniert, dann müssen Sie einen Blick in Abschnitt 4.4,
»Mapping von Primärschlüsseln«, werden.

Für die Klasse Bee legen Sie eine Datei Bee.hbm.xml im gleichen Java-Package an.
Als weiteres Tag wird hier <many-to-one> verwendet. Damit wird die Beziehung
aus Sicht der Klasse Bee beschrieben. Die assoziierte Klasse Honey müssen wir
nicht angeben. Sie wird von Hibernate aus dem Attribut der Java-Klasse ermittelt.

<class name="Bee" table="tbee" >


<id name="id" >
<generator class="sequence">
<param name="sequence" >bee_id_seq</param>
</generator>
</id>
<property name="name" type="string"></property>
<many-to-one name="honey"></many-to-one>
</class>

Warum type="string" und nicht type="java.lang.String"?


Wir können im Mapping auch Java-Klassen angeben. Hibernate-Typen sind aber prä-
ziser. Es gibt zum Beispiel die Typen date, timestamp und time, aber nur eine einzige
Java-Klasse java.util.Date.
Hibernate müsste raten, welchen Typen Sie meinen. Daher empfehle ich, immer die
Hibernate-Typen zu verwenden.
Generell ist die Angabe von type nur notwendig, wenn Hibernate den Typ nicht erra-
ten kann. Bei java.util.String könnten wir uns die type-Angabe auch sparen.

26
635-0.book Seite 27 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

1.1.4 Notwendige Bibliotheken


Um Hibernate zu verwenden, benötigen wir einige Bibliotheken, alias JAR-
Dateien.

Bei Hibernate hat von 2006 nach 2007 eine Explosion von Teilprojekten stattge-
funden. Erschrecken Sie sich nicht, wenn Sie Hibernate auf http://www.hiber-
nate.org/ herunterladen. Wir benötigen nur Hibernate Core und – wenn Sie
Annotations verwenden – Hibernate Annotations.

Entpacken Sie die Datei. Im Hauptverzeichnis finden Sie die hibernate.jar. Im lib-
Verzeichnis liegen eine Menge weiterer Bibliotheken, die wir aber nicht alle
benötigen. In der Datei README.txt ist erläutert, was wofür erforderlich ist.

Folgende Bibliotheken benötigen wir für unser Beispiel:

왘 log4j.jar
왘 hibernate3.jar
왘 ant-antlr-1.6.5.jar
왘 asm.jar
왘 commons-logging-1.0.4.jar
왘 antlr-2.7.6.jar
왘 cglib-2.1.3.jar
왘 dom4j-1.6.1.jar
왘 jdbc2_0-stdext.jar
왘 asm-attrs.jar
왘 commons-collections-2.1.1.jar
왘 ehcache-1.2.3.jar
왘 jta.jar
In Eclipse kann man diese in den Project Properties zum Java Build Path hinzu-
fügen. Der Dialog heißt: Add External Jars.

Um Annotations nutzen zu können, muss man Hibernate Annotations herunter-


laden. Wir benötigen folgende Bibliotheken:

왘 ejb3-persistence.jar
왘 hibernate-annotations.jar
왘 hibernate-commons-annotations.jar

27
635-0.book Seite 28 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

Datenbanktreiber
Natürlich ist auch ein JDBC-Datenbanktreiber notwendig. Die entsprechende
Bibliothek muss noch besorgt werden. Für PostgreSQL bekommt man diesen auf
http://jdbc.postgresql.org. Der JDBC 3-Treiber ist in Ordnung, wenn Sie Java
1.4 oder neuer verwenden.

Den MySQL Connector findet man auf:

http://www.mysql.com/products/connector/j/

Einen Oracle-Datenbank-Treiber erhält man bei Oracle: http://www.oracle.com

1.1.5 Session-Factory erstellen


Eine Session-Factory ist sehr wichtig für Hibernate. Wie der Name sagt, ist diese
Klasse eine Fabrik, mit der wir Hibernate-Sessions erzeugen können, wann
immer wir diese benötigen. Eine Session spielt eine zentrale Rolle in Hibernate.
Mit Hilfe einer Session können wir Daten speichern, löschen und die Datenbank
abfragen.

Die Session-Factory initialisiert auch die Hibernate-Konfiguration. Wir müssen


wieder Annotation und XML unterscheiden. Hier zuerst die Annotation-Version.

Von der Session-Factory sollte es nur eine Instanz geben (Singleton Pattern).
Genau dies stellt die folgende Klasse sicher.

package de.laliluna.hibernate;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
public class InitSessionFactory {
/** The single instance of hibernate SessionFactory */
private static org.hibernate.SessionFactory sessionFactory;
private InitSessionFactory() {
}
static {
final AnnotationConfiguration cfg = new
AnnotationConfiguration();
cfg.configure("/hibernate.cfg.xml");
sessionFactory = cfg.buildSessionFactory();
}
public static SessionFactory getInstance() {
return sessionFactory;
}
}

28
635-0.book Seite 29 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

Wenn wir XML Mapping einsetzen, können wir folgende Zeile statt Annotati-
onConfiguration verwenden.

final Configuration cfg = new Configuration();

Eine AnnotationConfiguration unterstützt allerdings neben Annotation auch


XML Mappings. Sie können diese sogar bunt mischen.

1.1.6 Logging Konfiguration


Hibernate verwendet log4j für die Logausgabe. Oben haben wir ja die Bibliothek
hinzugefügt. Log4j erwartet eine Konfigurationsdatei im Hauptverzeichnis, sonst
werden wir später mit folgender Nachricht begrüßt:

log4j:WARN No appenders could be found for logger (TestClient).


log4j:WARN Please initialize the log4j system properly.

Legen Sie eine Datei mit dem Namen log4j.properties im src-Verzeichnis an. Wir
konfigurieren eine einfache Logausgabe in der Console.

### direct log messages to stdout ###


log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p
%c{1}:%L - %m%n
# Achtung, die vorherige Zeile wird versehendlich umgebrochen
log4j.rootLogger=debug, stdout
log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug
### log just the SQL
log4j.logger.org.hibernate.SQL=debug

1.1.7 Datenbank und Tabellen erstellen


Erstellen Sie eine Datenbank und achten Sie darauf, den gleichen Namen zu wäh-
len, den wir in der connection.url der Hibernate-Konfiguration verwendet haben.

In der hibernate.cfg.xml haben wir festgelegt, dass die Tabellen von Hibernate
bei der Initialisierung erstellt werden, daher müssen wir das nicht von Hand erle-
digen.

<property name="hibernate.hbm2ddl.auto">create</property>

Die Einstellung create löscht die Tabellen und erstellt diese neu. Sie eignet sich
daher nur für die Entwicklung. Alternativ kann man die Einstellung update ver-
wenden. Hibernate versucht dann, die Tabellen nur bei Bedarf zu erzeugen bzw.

29
635-0.book Seite 30 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

zu ändern. Das klappt nahezu immer. Ich würde es für den Live-Betrieb dennoch
ausschalten.

1.1.8 Testen
Wir werden eine einfache Klasse erstellen, die unser Mapping verwendet, zudem
Daten erstellt, löscht und abfragt. Ich gebe Ihnen jetzt noch ein paar Hinweise
und schlage vor, dass Sie sich dann den Quellcode der Klasse ansehen.

Wenn Sie Hibernate verwenden, müssen Sie immer ein paar Dinge beachten:

왘 Sie brauchen immer eine Session, um auf Daten zuzugreifen.


왘 Der Datenzugriff muss immer innerhalb einer Transaktion erfolgen.
왘 Wenn etwas schief geht, müssen Sie die Transaktion zurückrollen.

Schauen Sie sich den folgenden Quellcode an, lassen Sie ihn einfach mal durch-
laufen und prüfen Sie, was in der Datenbank passiert.

In der Methode main rufen wir verschiedene Methoden auf, die Daten anlegen,
ändern, löschen oder anzeigen. Wenn in einer Methode eine Exception auftritt,
stellen wir sicher, dass unsere Transaktion zurückgerollt und die Hibernate-Ses-
sion geschlossen wird.

package de.laliluna.example;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.*;
import org.hibernate.transform.DistinctRootEntityResultTransformer;
import de.laliluna.hibernate.InitSessionFactory;
public class TestExample {
private static Logger log = Logger.getLogger(TestExample.class);
public static void main(String[] args) {
try {
clean();
createHoney();
createRelation();
delete();
update();
query();
initBees();
} catch (RuntimeException e) {
try {
Session session = InitSessionFactory.getInstance()
.getCurrentSession();

30
635-0.book Seite 31 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

if (session.getTransaction().isActive())
session.getTransaction().rollback();
} catch (HibernateException e1) {
log.error("Error rolling back transaction");
}
// throw the exception again
throw e;
}
}

Die Methode createHoney legt ein neues Objekt an und speichert es durch den
Aufruf von session.save in der Datenbank.

private static Honey createHoney() {


Honey forestHoney = new Honey();
forestHoney.setName("forest honey");
forestHoney.setTaste("very sweet");

Session session = InitSessionFactory.getInstance()


.getCurrentSession();
Transaction tx = session.beginTransaction();
session.save(forestHoney);
tx.commit();
return forestHoney;
}

Die Methode update lässt ein Objekt erzeugen, ändert dann den Namen und
aktualisiert das geänderte Objekt mit session.update.

private static void update() {


Honey honey = createHoney();
Session session = InitSessionFactory.getInstance()
.getCurrentSession();
Transaction tx = session.beginTransaction();
honey.setName("Modern style");
session.update(honey);
tx.commit();
}

Die Methode delete erzeugt gleichfalls ein Objekt und löscht es mit dem Aufruf
von session.delete sofort wieder.

private static void delete() {


Honey honey = createHoney();
Transaction tx = null;
Session session = InitSessionFactory.getInstance()
.getCurrentSession();

31
635-0.book Seite 32 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

Transaction tx = session.beginTransaction();
session.delete(honey);
tx.commit();
}

Die Tabellen werden von der Methode clean gesäubert. Die Methode session.cre-
ateQuery erzeugt eine Abfrage, die durch executeUpdate ausgeführt wird.

private static void clean() {


Session session = InitSessionFactory.getInstance()
.getCurrentSession();
Transaction tx = session.beginTransaction();
session.createQuery("delete from Bee").executeUpdate();
session.createQuery("delete from Honey").executeUpdate();
session.flush();
session.clear();
tx.commit();
}

Die Methode createRelation zeigt uns, wie man Objekte erzeugt und die Bezie-
hung zwischen den Objekten setzt. In der Datenbank wird eine Fremdschlüssel-
beziehung erstellt.

private static void createRelation() {


Session session = InitSessionFactory.getInstance()
.getCurrentSession();
Transaction tx = session.beginTransaction();
Honey honey = new Honey();
honey.setName("country honey");
honey.setTaste("Delicious");
session.save(honey);
Bee bee = new Bee("Sebastian");
session.save(bee);

/* Wir setzen die Beziehung auf BEIDEN Seiten */


bee.setHoney(honey);
honey.getBees().add(bee);
tx.commit();
}

Zum Schluss sehen wir ein einfaches Beispiel, wie Daten mit der Hibernate Query
Language (HQL) abgefragt werden. Die Abfrage wird wiederum mit session.crea-
teQuery erzeugt. Diesmal rufen wir aber die Methode list auf, da wir ein Ergebnis
erwarten.

32
635-0.book Seite 33 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

private static void query() {


Session session = InitSessionFactory.getInstance()
.getCurrentSession();
Transaction tx = session.beginTransaction();
List honeys = session.createQuery
("select h from Honey as h").list();
for (Iterator iter = honeys.iterator(); iter.hasNext();) {
Honey element = (Honey) iter.next();
log.debug(element);
}
tx.commit();
}
}

Das ging jetzt sehr schnell, aber Sie müssen nicht alles auf Anhieb im Detail ver-
stehen.

Das sollten Sie gelernt haben


Erstellen einer Klasse, die gemappt werden soll. Wichtig waren ein parameterloser
Default-Konstruktor, Serializable Interface, eine hübsche toString-Methode.
왘 Einfaches Mapping
왘 Speichern und Löschen von Objekten
왘 Eine einfache Abfrage

Warum gibt es den Try- und Catch-Block?


왘 Manche Datenbanken halten Ressourcen offen, wenn eine Transaktion nicht mit
commit oder rollback beendet wird. Deswegen gibt es das rollback nach einer
Exception.
왘 Nach einer Exception ist die aktuelle Session unbrauchbar. Wir müssen diese
schließen. In dem Beispiel verwenden wir die Einstellung current_session_
context="thread". Dieser Sessionkontext stellt sicher, dass beim Aufruf von com-
mit oder rollback die Session geschlossen wird. Sonst müssen wir die Methode
session.close() aufrufen.
왘 In einer normalen Anwendung reicht uns eine Stelle aus, die Transaktionen
zurückrollt und die Session – wenn erforderlich – schließt.
왘 Das könnten wir in einem Exception Handler von Struts, einem Interceptor von
MyFaces oder in einem Servletfilter vornehmen.

Unser Quellcode sieht also gewöhnlich einfach so aus:

Session session =
InitSessionFactory.getInstance().getCurrentSession();
Transaction tx = session.beginTransaction();

33
635-0.book Seite 34 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

session.save(honey);
tx.commit();

Müssen wir unsere Session nicht schließen?


Richtig, wir müssen eine Session immer schließen. Ich finde es praktisch, wenn die Ses-
sion automatisch nach einem commit oder rollback geschlossen wird. Der currentSes-
sionContext thread, den wir in der Hibernate-Konfiguration eingestellt haben, stellt
das für uns sicher. Wir brauchen daher nicht explizit ein session.close aufzurufen.

Deployment im JBoss Application-Server


Wenn Sie versuchen, dieses Beispiel oder eins der späteren im JBoss Application-Ser-
ver zu deployen, können Sie auf Schwierigkeiten stoßen.
JBoss bringt von Haus aus bereits Hibernate mit. Leider führt das zu unerwartetem
Verhalten in den Beispielen, da ich in der Hibernate-Konfiguration festlege, wie sich
die Session verhalten soll, und innerhalb vom JBoss dies teilweise ignoriert wird.
Entweder verwenden Sie vorerst den Tomcat Application-Server bzw. eine andere
Servlet Engine oder Sie werfen bereits jetzt einen Blick in die Abschnitte 2.3.2 und
5.4, »JTA versus JDBC Transaktionen«.

1.1.9 MyEclipse Tools für die Hibernate-Entwicklung


Es gibt zahlreiche Tools für die Entwicklung von Hibernate. Ich verwende MyE-
clipse, ein Plugin für Eclipse.

MyEclipse wird von Genuitec angeboten: http://www.myeclipseide.com/. Ich


verwende es für die Entwicklung von Webanwendungen. Es bietet Unterstüt-
zung für Spring, Hibernate, EJB, Struts, MyFaces und ist gewöhnlich auf einem
recht aktuellen Stand.

Hibernate-Unterstützung aktivieren
Mit MyEclipse können Sie Webprojekte direkt anlegen. Klickt man im Package
View mit der rechten Maustaste auf ein Projekt, kann man die Hibernate-Unter-
stützung im Kontextmenü aktivieren.

Abbildung 1.3 Hibernate-Unterstützung im Kontextmenü aktivieren

34
635-0.book Seite 35 Montag, 6. August 2007 12:52 12

Erstes Hibernate-Beispiel 1.1

Mit Hilfe des Wizards kann man:

왘 Bibliotheken hinzufügen
왘 Hibernate-Konfiguration erstellen
왘 Session-Factory erzeugen lassen

Über den Wizard kann man auch ein Connection Profile anlegen. Es konfiguriert
eine Datenbankverbindung mit Datenbanktreiber, Benutzernamen und Dialekt.

Abbildung 1.4 Ein Connection Profile erzeugen

Reverse Engineering
Hibernate liefert eigene Tools zur Erzeugung von Mapping-Dateien und Klassen
auf Basis einer existierenden Datenbank. MyEclipse integriert solche Funktionen
elegant in Eclipse.

Wenn Sie ein Connection Profile angelegt haben, öffnen Sie jetzt den View DB
Browser (MyEclipse) (siehe Abbildung 1.5).

Öffnen Sie das eben erstellte Connection Profile (siehe Abbildung 1.6).

35
635-0.book Seite 36 Montag, 6. August 2007 12:52 12

1 Einführung in Hibernate

Abbildung 1.5 Der View DB Browser

Abbildung 1.6 Das Profil öffnen

Wählen Sie die Tabellen aus, aus denen Sie Klassen, Mapping und DAOs erzeu-
gen möchten.

Der Wizard bietet Ihnen unterschiedliche Optionen, wie Sie die Tabellen erzeu-
gen können. Probieren Sie einfach die Möglichkeiten aus.

36
635-0.book Seite 37 Montag, 6. August 2007 12:52 12

Hibernate-Grundlagen 1.2

Abbildung 1.7 Die Auswahl der Tabellen

Hinweis
DAOs (Data Access Objects), die Sie ebenfalls mit dem Wizard erzeugen können,
besprechen wir zu einem späteren Zeitpunkt.

1.1.10 Andere Tools für die Hibernate-Entwicklung


Die Entwicklungsumgebungen IntelliJ und Netbeans verfügen von Haus aus über
Hibernate-Tools. Auf den Webseiten von Hibernate können Sie sich ferner die
Hibernate Tools herunterladen. Das ist ein Plugin für Eclipse.

1.2 Hibernate-Grundlagen
Sie wissen bereits, dass Hibernate ein Object-Relation-Mapping Framework ist.
Da Hibernate sogar ein besonders mächtiges ORM Framework ist, bietet es eine
ganze Menge an Funktionen.

1.2.1 Leistungsfähige Mapping-Varianten


Ein Mapping muss nicht immer aus eine Klasse pro Tabelle bestehen. Wir kön-
nen eine Vielzahl von objektorientierten Konzepten mit Hilfe der Mappings dar-
stellen.

Im ersten Beispiel haben Sie eine Beziehung zwischen Klassen kennen gelernt.
Das entspricht in der Objektorientierung einer Assoziation. Mit Hibernate kön-

37
635-0.book Seite 285 Montag, 6. August 2007 12:52 12

In diesem Kapitel werden Sie lernen, wie Sie Hibernate in andere Techno-
logien integrieren und Exceptions mit diesen Technologien behandeln. Ich
werde einige Fallstricke nennen, damit Sie möglichst wenig Schwierigkei-
ten bei der Integration haben werden.

5 Integration anderer Technologien

Spring ist ein wunderbares Framework, um die Geschäftslogikschicht zu imple-


mentieren. Es kann Hibernate auf elegante Weise integrieren. Spring können Sie
auf der Seite http://www.springframework.org/ herunterladen. Dieses Kapitel
setzt voraus, dass Sie das Spring Framework kennen, weil ich keine Spring-
Grundlagen erklären werde.

5.1 Hibernate und Spring


Die Dokumentation zu Spring stellt drei Alternativen vor. Ich halte eine von
ihnen für nicht sehr schön und werde daher nur zwei Möglichkeiten erläutern.

Beide Beispiele verwenden Spring in der Version 2 mit Annotations. Sie benöti-
gen daher Java 5 oder aktueller. Wenn Sie Java 1.4 verwenden, müssen Sie das
Transaktionshandling anders konfigurieren. Das werde ich an entsprechender
Stelle erläutern.

5.1.1 Konfiguration
Sie haben drei Möglichkeiten der Konfiguration von Hibernate, wenn Sie Spring
verwenden:

왘 Verweis in der Spring-Konfiguration auf eine Hibernate-Konfigurationsdatei


왘 Vollständige Konfiguration von Hibernate in der Spring-Konfigurationsdatei
왘 Mischen der beiden Ansätze

Ich würde die letzte Möglichkeit empfehlen, weil einige Entwicklungsumgebun-


gen Textvervollständigung für Hibernate-Einstellungen in der Hibernate-Konfi-
gurationsdatei anbieten. Nachfolgende Abbildung zeigt das für Eclipse mit dem
MyEclipse-Plugin:

285
635-0.book Seite 286 Montag, 6. August 2007 12:52 12

5 Integration anderer Technologien

Abbildung 5.1 Textvervollständigung mit dem MyEclipse-Plugin

Eine Konfiguration in Spring umfasst eine Datenquelle und eine vom Spring Fra-
mework zur Verfügung gestellte Session-Factory. Es ist wichtig, dass wir diese
verwenden, sonst funktioniert die Integration nicht ordentlich und es können
Connection Leaks auftreten.

<bean id="datasource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="org.postgresql.Driver" />
<property name="jdbcUrl"
value="jdbc:postgresql://localhost:5432/learninghibernate" />
<property name="user" value="postgres" />
<property name="password" value="p" />
<property name="minPoolSize" value="2" />
<property name="maxPoolSize" value="4" />
</bean>

<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.annotation.
AnnotationSessionFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>

Die Hibernate-Konfigurationsdatei ist sehr kurz und enthält keine Angaben zur
Datenquelle oder zum Verhalten der Session.

286
635-0.book Seite 287 Montag, 6. August 2007 12:52 12

Hibernate und Spring 5.1

<hibernate-configuration>
<session-factory>
<property name="dialect">
org.hibernate.dialect.PostgreSQLDialect
</property>
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<property name="hbm2ddl.auto">none</property>
<mapping class="de.laliluna.example.domain.Hedgehog" />
<mapping class="de.laliluna.example.domain.WinterAddress" />
</session-factory>
</hibernate-configuration>

Problembereich
Sie sollten auf keinen Fall die Datenquelle in der Hibernate-Konfigurationsdatei fest-
legen. Wenn doch, bekommen Sie Probleme, sobald Sie die Transaktionssteuerung
von Spring verwenden.

Alternativ können Sie alle Einstellungen der Session-Factory vollständig in Spring


konfigurieren.

<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.annotation.
AnnotationSessionFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="annotatedClasses">
<list>
<value>de.laliluna.example.domain.Hedgehog</value>
<value>de.laliluna.example.domain.WinterAddress</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.hbm2ddl.auto=none
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.cache.provider_class=org.hibernate.cache
.EhCacheProvider
</value>
</property>
</bean>

Unser Beispiel hat eine Session-Factory gezeigt, die Annotations unterstützt.


Wenn Sie nur XML Mappings einsetzen, können Sie auch die Klasse org.springf-
ramework.orm.hibernate3.LocalSessionFactoryBean auswählen.

287
635-0.book Seite 288 Montag, 6. August 2007 12:52 12

5 Integration anderer Technologien

Warum keine Hibernate-Session-Factory?


Es wäre möglich, statt der Spring-Session-Factory unsere Hibernate-Session-Factory
aus den bisherigen Beispielen zu verwenden. Dann müssten wir auch eins der in
Abschnitt 2.3, »Session und Transaktionen«, vorgestellten Pattern verwenden.
Session session = factory.getCurrentSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// do some work
tx.commit();
} catch (RuntimeException e) {
try {
if (tx != null)
tx.rollback();
} catch (HibernateException e1) {
log.error("Transaction roleback not succesful", e1);
}
throw e;
}
Spring bietet uns eine Möglichkeit, Transaktionen auf eine komfortablere Art zu steu-
ern. Die Transaktionssteuerung ist übergreifend und kann eine Hibernate- und eine
JDBC-Transaktion einschließen. Auf diese elegante Möglichkeit verzichten wir, wenn
wir die Hibernate-Session-Factory verwenden.
Ich empfehle, lieber die Möglichkeiten von Spring zu verwenden. Dabei müssen Sie
aber auf die Nutzung der Hibernate-Transaktionssteuerung verzichten, sonst hat
Spring erhebliche Schwierigkeiten, Datenbankverbindungen und Hibernate-Sessions
freizugeben. Verwenden Sie also auf keinen Fall session.beginTransaction(), wenn Sie
sich für den »Spring Weg« entscheiden.

5.1.2 Verwendung des Spring Templates


In diesem Abschnitt werden wir die erste Möglichkeit kennen lernen, Spring und
Hibernate zu integrieren. Sie finden eine vollständige Implementierung im Pro-
jekt HibernateSpring (http://www.galileocomputing.de/978). Die Bibliotheken
können Sie von der Spring Framework-Webseite herunterladen. Sie benötigen
die Download-Version mit allen Abhängigkeiten. Das Beispielprojekt verwendet
die Bibliotheken:

왘 spring.jar
왘 aspectjrt.jar
왘 spring-aspects.jar
왘 aspectjweaver.jar

288
635-0.book Seite 289 Montag, 6. August 2007 12:52 12

Hibernate und Spring 5.1

Spring bietet für unterschiedliche Persistenztechnologien ein Template an, das


die Implementierung und technologiespezifische Exceptions kapselt und in ein-
heitliche Spring Exceptions umwandelt. Diese Templates existieren für

왘 Hibernate
왘 JDO
왘 Ibatis
왘 Toplink
왘 JPA
왘 JDBC

Wenn Sie unterschiedliche Technologien verwenden, ist das Template ein guter
Ansatz, um ein einheitliches Verhalten und eine globale Transaktionssteuerung
zu erreichen.

Zunächst wird ein Hibernate Template erzeugt. Dieses benötigt die vorhin konfi-
gurierte Spring-Session-Factory.

HibernateTemplate template = new HibernateTemplate(factory);

Das Template wird verwendet, um Hibernate zu kapseln. Das unten stehende


Beispiel zeigt die Verwendung. Sie lesen den Quellcode am besten von innen
nach außen.

return (List<Hedgehog>) template.execute(new HibernateCallback() {


public Object doInHibernate(Session session)
throws HibernateException, SQLException {
return session.createCriteria(Hedgehog.class).list();
}
});

Mit new HibernateCallback() erzeugen wir eine anonyme Implementierung des


Interfaces HibernateCallback. Das Interface hat genau eine Methode: doInHiber-
nate. Die Methode bekommt von Spring als Parameter eine Hibernate-Session
übergeben. Die eigentliche Arbeit wird in der Zeile return session.get(Hedge-
hog.class, id) verrichtet.

Wir übergeben der Methode execute des Templates diese frisch erstellte Imple-
mentierung zur Ausführung.

Diese Konstruktion mag ungewöhnlich erscheinen, ermöglicht aber Spring, die


Ausführung des Hibernate-Codes zu kapseln, Ausnahmen umzuwandeln und
sicherzustellen, dass, wenn eine Exception im Hibernate-Code auftritt, die Trans-

289
635-0.book Seite 290 Montag, 6. August 2007 12:52 12

5 Integration anderer Technologien

aktion zurückgerollt und die Session geschlossen wird. Bisher mussten Sie das
immer selbst erledigen.

Der aufmerksame Leser wird sich jetzt vielleicht fragen, welche Transaktion
zurückgerollt wird. Schließlich haben wir keine Transaktion begonnen. Wenn
wir nicht explizit eine Transaktion festlegen, stellt Spring das Transaktionsverhal-
ten der JDBC-Verbindung auf auto-commit. Jede Abfrage läuft dann in einer
Transaktion. Wie das Transaktionsverhalten explizit gesteuert wird, sehen wir
uns im übernächsten Abschnitt an.

Am Ende noch ein wichtiger Hinweis: Das Hibernate Template bietet für viele
Methoden der Hibernate-Session bereits eine fertige Implementierung: save,
saveOrUpdate, delete, update und viele mehr. Diese können Sie beruhigt verwen-
den.

template.save(hedgehog);

Problembereich des Hibernate Templates


Ich rate dringend davon ab, die unterschiedlichen find-Methoden des Hibernate
Templates zu verwenden. Das Template hat globale Einstellung für die maximale
Anzahl von Zeilen, die eine Abfrage zurückliefert, zum Verhalten in Bezug auf den
Cache und diversen anderen Parametern. So können Sie »interessante«, aber uner-
wartete Ergebnisse erhalten.
Schreiben Sie Ihre Abfragen lieber selbst und kapseln Sie diese, wie oben gezeigt, in
einem HibernateCallBack.

5.1.3 Alternative zum Spring Template


Es gibt sicherlich schöneren Quellcode als das oben gezeigte Template. Ich
möchte Ihnen daher eine Alternative zeigen, die auf dieses Konstrukt verzichtet.
Wir verwenden die Methode getCurrentSession, die uns auch in der Spring-Ses-
sion-Factory zur Verfügung steht. Ähnlich wie bei der Verwendung eines Cur-
rentSessionContext rufen wir diese Methode überall auf, wo wir eine Hibernate-
Session benötigen.

protected Session getCurrentSession() {


return factory.getCurrentSession();
}
public void save(Hedgehog object) {
getCurrentSession().saveOrUpdate(object);
}

290
635-0.book Seite 291 Montag, 6. August 2007 12:52 12

Hibernate und Spring 5.1

Unser Quellcode funktioniert damit aber noch nicht. Bei diesem Ansatz müssen
wir explizit eine Transaktion vor dem Aufruf von getCurrentSession starten. Wie
das geht, zeige ich im nächsten Abschnitt.

Exception Handling
Die Spring-Dokumentation behauptet, dass wir durch diesen Ansatz statt mit einheit-
lichen Spring Exceptions mit Hibernate Exceptions umgehen müssen.
Das ist nicht sehr präzise ausgedrückt. Die Exception wird nur später umgewandelt.
Unser erster Ansatz mit Templates wandelt die Exception sofort im Template um. Der
zweite Ansatz wandelt die Exception erst im Rahmen der Transaktionssteuerung um.
Das bedeutet, dass die Methode in unserer Klasse HedgeHogServiceImp bereits abge-
arbeitet ist. Da Hibernate Exceptions gewöhnlich fatal sind und erst im Frontend-
Layer – zum Beispiel in der Webanwendung – behandelt werden, ist uns dieses Ver-
halten egal.
Der zweite Ansatz ist meiner Meinung nach eine gute Wahl, da er besser zu lesen ist
und weniger Schreibarbeit erfordert.

5.1.4 Transaktionssteuerung
Es ist sehr einfach, Transaktionen mit Spring zu steuern. In der Spring-Konfigu-
rationsdatei müssen Sie nur einen Transaktionsmanager konfigurieren. In diesem
Beispiel verwenden wir einen JDBC-basierten Transaktionsmanager.

<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager"
class="org.springframework.orm.hibernate3.
HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>

Hinweise zur Konfiguration eines JTA-basierten Transaktionsmanagers finden


Sie in der Spring-Dokumentation. Die Konfiguration hängt immer vom Applica-
tion-Server ab.

Innerhalb der Anwendung sind Transaktionen leicht zu integrieren. Wir müssen


nur die Annotation @Transactional vor eine Methode schreiben. Spring wird
dann vor der Methode die Transaktion starten und nach der Methode ein commit
aufrufen.

@Transactional(propagation = Propagation.REQUIRED)
public void update(Hedgehog hedgehog) {
hedgehogDao.update(hedgehog);
}

291
635-0.book Seite 292 Montag, 6. August 2007 12:52 12

5 Integration anderer Technologien

propagation legt die Art der Transaktion fest. Ich habe eine Übersicht über die
Transaktionsarten zusammengestellt.

Art der Transaktion Verhalten


REQUIRED Eine Transaktion ist erforderlich. Wenn keine Transaktion geöff-
net ist, wird eine begonnen und nach der Methode abgeschlos-
sen. Sonst läuft die Methode innerhalb der bestehenden Transak-
tion.
Diese Einstellung ist der Vorgabewert.
SUPPORTS Transaktionen werden unterstützt, aber es wird keine Transaktion
gestartet. Wenn es eine gibt, läuft die Methode innerhalb der
Transaktion, wenn nicht, wird die Methode einfach so aufgeru-
fen.
MANDATORY Es ist eine Transaktion erforderlich, aber es wird keine gestartet.
Wenn es eine gibt, läuft die Methode innerhalb der Transaktion,
wenn nicht, wird eine Exception geworfen.
REQUIRES_NEW Es ist eine Transaktion erforderlich und es wird immer eine neue
gestartet. Wenn es bereits eine gibt, wird diese pausiert. Nicht
alle Transaktionsmanager unterstützen diese Möglichkeit.
NOT_SUPPORTED Die Methode kann nicht innerhalb einer Transaktion aufgerufen
werden. Wenn eine Transaktion existiert, wird diese pausiert.
Nicht alle Transaktionsmanager unterstützen diese Möglichkeit.
NEVER Die Methode kann nicht innerhalb einer Transaktion aufgerufen
werden. Wenn eine Transaktion existiert, wird eine Exception
geworfen.
NESTED Es wird eine verschachtelte Transaktion gestartet, also innerhalb
einer bestehenden Transaktion wird eine weitere gestartet. Sie
können den Transaktionsmanager DataSourceTransactionMana-
ger verwenden. Verschachtelte Transaktionen werden allerdings
nur von wenigen Datenbanken unterstützt. Manche JTA-Transak-
tionsmanager unterstützen gleichfalls JTA.

Wenn eine Exception vom Typ RuntimeException innerhalb der Methode auf-
tritt, führt Spring automatisch ein Rollback der Transaktion durch. Das gilt nicht
für die so genannten Checked Exceptions. Das Rollback-Verhalten können Sie für
Checked Exceptions festlegen. Mehr Informationen dazu finden Sie in der
Spring-Dokumentation.

Tipp: Transaktionskonfiguration auf Klassenebene


Sie können die Annotation @Transactional auch vor die Klasse schreiben. Dann ver-
wendet Spring für alle öffentlichen Methoden der Klasse eine Transaktion. Die Anno-
tation auf Klassenebene ist eine Vorgabe für die Methoden. Wenn sich eine Methode
anders verhalten soll, so können Sie dort einfach eine weitere Annotation einfügen
und den Vorgabewert überschreiben.

292
635-0.book Seite 293 Montag, 6. August 2007 12:52 12

Hibernate und Struts 5.2

Transaktionen ohne Annotation


Die Verwendung von Annotations für die Konfiguration ist meiner Meinung nach
eine sehr schöne Lösung. Wenn Sie ein älteres JDK als Version 5 verwenden müssen,
stehen Ihnen Annotations leider nicht zur Verfügung.
In diesem Fall würde man die Transaktionen entweder explizit im Quellcode steuern
oder über die Spring-Konfigurationsdatei festlegen. Mehr Informationen dazu finden
Sie in der Spring-Dokumentation.

5.2 Hibernate und Struts


Ich habe eine kleine Beispielanwendung geschrieben, die Sie auf der Webseite
zum Buch (http://www.galileocomputing.de/978) finden. Diese Anwendung
orientiert sich an Best Practices und Sie können sie als hochwertige Vorlage ver-
wenden. Das Projekt heißt Hibernatestruts. Die Anwendung setzt die Ajax-Tech-
nologie ein, zeigt eine Liste von Igeln und erlaubt, Igel zu erstellen und zu bear-
beiten. Als Datenbank habe ich PostgreSQL eingesetzt.

Folgende Bibliotheken habe ich verwendet:

왘 Struts 1.3
왘 Displaytag 1.1 (http://displaytag.sourceforge.net/11/)
왘 Hibernate 3.2 Core und Annotation
왘 Ajaxtags 1.2 (http://ajaxtags.sourceforge.net/)
왘 Prototype Ajax 1.5.0 (http://www.prototypejs.org/)
왘 Script.aculo.us 1.7.0 (http://script.aculo.us/)

Die Anwendung demonstriert:

왘 Einsatz von Geschäfts- und DAO-Layer


왘 Verwendung einer generischen Dao-Implementierung
왘 Optimistisches Sperren
왘 Zentraler Umgang mit Exception

Ich werde die letzten beiden Punkte im Folgenden im Detail erklären.

5.2.1 Optimistisches Sperren


Optimistisches Sperren bedeutet, dass Hibernate prüft, ob ein anderer Benutzer
einen Datensatz bereits geändert hat, seitdem die Daten geladen worden sind.

293
635-0.book Seite 361 Montag, 6. August 2007 12:52 12

Index

<array> 203 @EmbeddedId 184, 325


<bag> 195 @Entity 24, 319
<cache> 160 @EntityResult 354
<collection-id> 202 @Enumerated 329
<component> 246 @Fetch 338
<composite-element> 248 @FieldResult 354
<composite-id> 187, 239, 256 @Filter 348
<discriminator> 264 @FilterDef 349
<formula> 239 @Filters 348
<generator class=foreign> 216 @Formula 331
<idbag> 202 @GeneratedValue 24, 324
<join table=..> 272 @GenericGenerator 327
<join> 227 @Id 24, 324
<joined-subclass> 268 @IdClass 186, 325
<list> 201 @Index 322
<many-to-any> 280 @IndexColumn 201, 247, 337
<many-to-many> 226, 229 @Indexed Hinweis 222
<many-to-one> 211, 220 @Inheritance 263, 267, 343
<map> 198 @JoinColumn 24, 335
<map-key> 198 @JoinColumns 335
<meta-value> 280 @JoinTable 226, 228, 336
<one-to-one> 214 @LazyCollection 342
<parent> 246 @LazyToOne 343
<primitive-array> 204 @Length 133
<set 218 @Lob 135, 329
<set> 193, 218 @ManyToMany 228, 333
<subclass> 264, 272 @ManyToOne 24, 220, 332
<union-subclass> 277 @MapKey 198, 339
<version 101 @MapKeyManyToMany 234
@AccessType 345 @MappedSuperclass 282, 345
@AttributeOverride 330 @NamedNativeQueries 129, 352
@Basic 328 @NamedNativeQuery 353
@BatchSize 117, 342 @NamedQueries 128, 350
@Cache 347 @NamedQuery 128, 350–351
@Cascade 338 @NotFound 340
@Check 347 @OnDelete 340
@CollectionOfElements 203, 247, 252, @OneToMany 24, 218, 332
334 @OneToOne 210, 331
@Column 328 @OrderBy 341
@ColumnResult 355 @org.hibernate.annotations
@DiscriminatorColumn 263, 344 AccessType 345
@DiscriminatorFormula 345 BatchSize 342
@DiscriminatorValue 344 Cache 347
@Embeddable 245, 248, 334 Cascade 338
@Embedded 245, 333 Check 347

361
635-0.book Seite 362 Montag, 6. August 2007 12:52 12

Index

CollectionOfElements 334 A
DiscriminatorFormula 345
Entity 319 Abfragen
Fetch 338 @NamedQueries 128
Filter 348 @NamedQuery 128
FilterDef 349 AliasToBeanResultTransformer 109
Filters 348 all 113
Formula 331 any 113
GenericGenerator 327 createAlias 111
Index 322 DetachedCriteria 113
IndexColumn 337 executeUpdate 115
LazyCollection 342 exists 113
LazyToOne 343 gtAll 113
MapKey 339 gtSome 114
NamedQueries 350 in 113
NamedQuery 351 left join fetch 118
OnDelete 340 MatchMode.START 110
OrderBy 341 Parameter 112
ParamDef 349 Property.forName 113
Parameter 347 Restrictions.disjunction 111
Parent 334 Restrictions.eq 109
Table 322 Restrictions.in 110
Type 346 Restrictions.isEmpty 114
TypeDef 347 Restrictions.like 110
TypeDefs 346 Restrictions.lt 111
Where 341 Restrictions.or 111
@org.hibernate.NotFound 340 setFetchMode 118
@ParamDef 349 setParameterList 110
@Parameter 347 setReadOnly 108
@Parent 245, 334 some 113
@PersistenceContext 308 uniqueResult 112
@PrimaryKeyJoinColumn 216, 336 Where-Bedingung mit Beziehungen 111
@PrimaryKeyJoinColumns 337 abstract 176
@QueryHint 128, 351 action = NotFoundAction.IGNORE 340
@SecondaryTable 323 after_statement 146
@SequenceGenerator 24, 325 after_transaction 146
@SqlResultSetMapping 129, 354 Aggregation 244
@SqlResultSetMappings 353 AliasToBeanResultTransformer 109
@Table 322 all 113
@TableGenerator 326 allocationSize 124, 325
@Target 170 Annotation 167
@Temporal 329 AnnotationConfiguration 29
@TransactionAttribute 308 Annotation-Nachteile 169
@Transient 328 Annotations an Felder, Methoden und
@Type 346 Klassen 170
@TypeDefs 130, 346–347 AnnotationSessionFactoryBean 286
@UniqueConstraint 323 Annotation-Vorteile 168
@Version 101, 330 any 113
@Where 341 appliesTo = tableName 322

362
635-0.book Seite 363 Montag, 6. August 2007 12:52 12

Index

Architektur all 208


Geschäftslogik 39 all-delete-orphan 208
Persistenz Layer 39 CascadeType 338
Webanwendung 39 CascadeType.ALL 208
Array 190 CascadeType.DELETE_ORPHAN 208
ArrayList 189–190 CascadeType.REFRESH 207
Assoziation 17, 37, 188, 244 CascadeType.REMOVE 207
ASTQueryTranslatorFactory 152 delete 208
auto-import 172 delete-orphan 208
evict 208
B Fehlerpotenzial 209
lock 208
Bag 189 MERGE 208
batch-size 175 PERSIST 208
Bibliotheken 27 persist 208
Bidirektional 205 REFRESH 208
BinaryType 136 refresh 208
BLOB 134 REMOVE 208
BLOB Lazy Loading 126 replicate 208
Blob-Felder 149 save-update 208
BlobType 137 catalog 172, 174
bytea 136 catalog = catalogName 322
Bytecode-Instrumentation 126–127 cglib.use_reflection_optimizer 144, 152
check 176
C class 173
ClassicQueryTranslatorFactory 152
C3P0 153 clause = deleted=false 341
c3p0.* 145 clear() 124
Cache CLOB 126, 134
Cache 157 CLOB Lazy Loading 126
Cache deaktivieren 149 Clustering 149
Cache Modus 159 Collection 189
Cache verwenden 161 Component Mapping 243
nonstrict-read-write 159 Configuration 29
Query Cache 162 Connection Pool
read-only 159 Connection Pool 152
read-write 159 Connection Pool mit Jboss 156
transactional 159–160 Connection Pool mit Tomcat 154
cache.provider_class 149 connection.autocommit 146
cache.query_cache_factory 149 connection.datasource 145
cache.region_prefix 150 connection.driver_class 145
cache.use_minimal_puts 149 connection.eineEinstellung 146
cache.use_query_cache 149 connection.isolation 146
cache.use_second_level_cache 149 connection.password 145
cache.use_structured_entries 150 connection.provider_class 146
CacheConcurrencyStrategy 348 connection.release_mode 146
CacheModeType 351 connection.url 23, 145
Cache-Regionen 150 connection.username 145
Cascading 48, 207 context.xml 154

363
635-0.book Seite 364 Montag, 6. August 2007 12:52 12

Index

createAlias 111 Entity 167, 173


createSQLQuery 115 Entity-Manager 301
Criteria Queries 39 EntityManagerFactory 303
Criteria.DISTINCT_ROOT_ENTITY 43 entity-name 176
Criteria-Abfragen 104 EnumType.ORDINAL 329
current_session_context 33 EnumType.STRING 329
current_session_context_class 147 EventListener 132
Eventsystem 132
D Exception 30, 89
LazyInitializationException 41, 94
DAO NonUniqueObjectException 50
DAO Factory 77 StaleObjectStateException 51
Dao mit SessionFactory vs Session 78 Exception Handling 68
DAOs mit Generics 81 Exception Handling in JPA 305
DAOs mit Java 1.4 84 Exception Handling mit JSF (MyFaces)
Data Access Objects (DAO) 74 296
Kluge DAO 86 Exception Handling mit Spring 292
Datenbanktreiber 28 Exception Handling mit Struts 294
DBCP 153 Try und Catch 33
Debugging 115 Try und Catch in Webanwendung 68
default_batch_fetch_size 118, 151 executeUpdate 115
default_catalog 151 exists 113
default_entity_mode 150 explicit 175
default_schema 150
default-access 172 F
default-cascade 172
default-lazy 172 fetch=FetchType.EAGER 331
DefaultLoadEventListener 132 FetchMode.JOIN 339
DerbyDialect 23 FetchMode.SELECT 339
detached 44 FetchMode.SUBSELECT 339
DetachedCriteria 113 find 304
dialect 22, 144 First Level Cache 87
Discriminator Column 38 First-Level-Cache 157
discriminatorType 263 flush() 124
discriminatorType = Discriminator- FlushMode 97
Type.STRING 344 flushMode 351
DiscriminatorType.CHAR 344 FlushModeType.AUTO 351
DiscriminatorType.INTEGER 344 Foreign Key Constraint 205
DiscriminatorType.STRING 263, 344 format_sql 116
discriminator-value 173 Fremdschlüsselspalte 24
dom4j 150
dynamic insert 129, 174, 320 G
dynamic update 101, 129, 174, 320
dynamic-map 150 generate_statistics 151
GeneratedValue 168
E GenerationType 168
GenerationType.AUTO 324
EH Cache 164 GenerationType.IDENTITY 324
EJB 3 301 GenerationType.SEQUENCE 324

364
635-0.book Seite 365 Montag, 6. August 2007 12:52 12

Index

GenerationType.TABLE 324 guid 181


Generics 20 hashCode 183
getReference 307 hilo 181
Glassfish 310 Id 176
gtAll 113 identity 181
gtSome 114 increment 182
künstlicher Schlüssel 178
H MultipleHiLoPerTableGenerator 182
native 181
HashMap 190 Natürliche Schlüssel 177
HashSet 190 select 181
hbm2ddl.auto 22, 150 seqhilo 181
Hibernate Validator 133 sequence 181
hibernate.cfg.xml 143 Trigger 181
hibernate.hbm2ddl.auto 29 unsaved-value 182
Hibernate.initialize 43 uuid 182
hibernate.jdbc.use_streams_for_binary implicit 175
144 in 113
hibernate.properties 143 indexes 322
hibernate3.jar 27 Inheritance 257
hibernate-annotations.jar 27 InheritanceType.JOINED 267, 343
HibernateCallBack 290 InheritanceType.SINGLE_TABLE 263,
hibernate-mapping 172 343
HibernateServiceBean 298 InheritanceType.TABLE_PER_CLASS 275,
Hibernate-Typen 26 343
hints = {@QueryHint(...)} 350 initialValue=1 325
HQL 32, 38, 103 inner join 106
HQL-, Criteria- und SQL-Vergleich 103 insert=false 206
HSQLDialect 23 InstrumentTask 127
Interceptor 131
I inverse 206
inverseJoinColumns 228, 336
Id 168 Inversion of Control 308
<composite-id> 185
<generator class=native> 179 J
<id> 182
<key-property> 185 Java Persistence API 301
@EmbeddedId 184 JavaServer Faces 295
@IdClass 186 Exception Handling 296
assigned 178, 181 javax.persistence. 167
Composite Id 183 JBoss Application-Server 34
equals 183 JBoss Cache 166
foreign 182 JBoss JPA 311
GenerationType.AUTO 179 JBoss Treecache 166
GenerationType.IDENTITY 180 jdbc.batch_size 148
GenerationType.SEQUENCE 179 jdbc.batch_versioned_data 148
GenerationType.TABLE 180 jdbc.factory_class 148
generator class 182 jdbc.fetch_size 148
GenericGenerator 180 jdbc.use_get_generated_keys 149

365
635-0.book Seite 366 Montag, 6. August 2007 12:52 12

Index

jdbc.use_scrollable_resultset 148 L
jdbc.use_streams_for_binary 149
JDBCTransactionFactory 90 lazy 175
JDBC-Transaktionen 88 Lazy Initialization 40, 47
Jgroups 165 LazyCollectionOption.EXTRA 342
JNDI 154 LazyCollectionOption.FALSE 342
JNDI Connection Pool 154 LazyCollectionOption.TRUE 342
jndi.class 145 Lazy-Fetching 42
jndi.eineEinstellung 145 LazyInitializationException 41, 95
jndi.url 145 LazyToOneOption.FALSE 343
Join 106 LazyToOneOption.NO_PROXY 343
joinColumns 228, 336 LazyToOneOption.PROXY 343
JPA 301 left join fetch 43, 118
JPA und EJB3 List 190
@TransactionAttribute 308 LoadEventListener 132
Entity-Manager 301 LOB (Large Object) 134
EntityManager 304 LocalSessionFactoryBean 287
EntityManagerFactory 303–304 LockMode.NONE 51
find 304 LockMode.READ 51
getReference 307 LockMode.UPGRADE 51, 103
Glassfish 310 Logging
Inversion of Control 308 log4j 29
JBoss 311 log4j.logger.org.hibernate.cache 116
JPA 301 log4j.logger.org.hibernate.id 116
JPA – Java-Persistenz-API 171 log4j.logger.org.hibernate.SQL 116
persist 304 log4j.logger.org.hibernate.type 116
persistence.xml 302 Löschen von Daten 53
Persistenz-Provider 302 Lucene 134
remove 304
Toplink 301 M
TransactionAttributeType 308
MANDATORY 309 Map 190
NEVER 309 mappedBy 206
NOT_SUPPORTED 309 Mapping
REQUIRED 309 Beziehungen 187
REQUIRES_NEW 309 Komponenten 243
SUPPORTS 309 Vererbung 257
JTA – Java Transaction API 88 Vor- und Nachteile 190
jta.UserTransaction 148 Mapping von Beziehungen
<array> 203
K <bag> 195
<collection-id> 202
Komponenten Mapping 243 <idbag> 202
Komposition 38, 244 <join> 227
Konfiguration <list> 201
Konfiguration mit Java 144 <many-to-many> 226, 229
Konkurrierender Zugriff 100 <many-to-one> 211, 220
Konstruktor 20, 58 <map> 198
Konversationen 94 <map-key> 198

366
635-0.book Seite 367 Montag, 6. August 2007 12:52 12

Index

<one-to-one> 214 @Embedded 245


<primitive-array> 204 @Parent 245
<set> 193, 218 einfache Komponente 244
@AttributeOverrides 197 Fehlerpotenzial bei non-indexed 249
@CollectionOfElements 197, 203 Komponenten 243
@Column 197 Liste von Komponenten 247
@IndexColumn 201, 203 Set von Komponenten 249
@JoinColumn 192, 194, 197 zusammengesetzte Primärschlüssel 254
@JoinTable 197, 226, 228 Mapping von Vererbung
@ManyToMany 228 <discriminator> 264
@ManyToOne 220 <join table=..> 272
@MapKey 198 <joined-subclass> 268
@MapKeyManyToMany 234 <many-to-any> 280
@OneToMany 192, 194, 201, 218 <meta-value> 280
@OneToOne 210 <subclass> 264, 272
@PrimaryKeyJoinColumn 216 <union-subclass> 277
@Sort 194 @DiscriminatorColumn 263
1:1 Beziehung 210 @Inheritance 263
1:n-Beziehung 216 @MappedSuperclass 282
Array 191 Auswahl des Mapping-Ansatzes 259
Bag 190, 195 Discriminator Column 38
bidirektional 205 discriminatorType 263
Fehlerpotenzial manyToMany 230 DiscriminatorType.STRING 263
Foreign Key Constraint 205 InheritanceType.JOINED 267
insert=false 206 InheritanceType.SINGLE_TABLE 263
inverse 206 InheritanceType.TABLE_PER_CLASS 275
inverseJoinColumns 228 Klassenhierarchie in einer Tabelle 262
joinColumns 228 Klassenhierarchie mit einer Tabelle für jede
List 191 konkrete Klasse 274
m:n-Beziehung 227 Klassenhierarchie mit einer Tabelle pro
Map 191, 196 Klasse 266
mappedBy 206 Klassenhierarchie mit einer Tabelle pro
property-ref 214 Klasse + Discriminator 271
rekursive Beziehung 236 Klassenhierarchie mit einer Tabelle pro
Set 190, 192 Unterklasse 279, 281
SortedMap 191 Vererbung 257
SortedSet 190, 193 MatchMode.START 110
strategy = foreign 216 max_fetch_depth 151
unidirektional 204 mutable 173
update=false 206 mutable = true 320
Verwalten der Beziehung 206 MyFaces 295
Vor- und Nachteile 190 MySQL5Dialect 23
Mapping von Komponenten
<component> 246 N
<composite-element> 248
<composite-id> 256 name 173
<parent> 246 Named Queries 128
@CollectionOfElements 247 node 176
@Embeddable 245 NonUniqueObjectException 50, 95

367
635-0.book Seite 368 Montag, 6. August 2007 12:52 12

Index

NotFoundAction.EXCEPTION 340 Property.forName 113


NotFoundAction.IGNORE 340 PropertyAccessor 172, 183
property-ref 214
O proxy 174

Object-Relational-Mapping 13 Q
oid 136
on_close 146 query = fromComputerBook), 350
OnDeleteAction.CASCADE 340 Query Cache 163
OnDeleteAction.NO_ACTION 340 query.factory_class 152
Open-Session-in-View 42, 96 query.substitutions 152
optimisticLock 101, 175
OptimisticLockType.ALL 101, 321 R
OptimisticLockType.DIRTY 102, 321
OptimisticLockType.VERSION 321 Read-Only-Mapping 120
Optimistisches Sperren referencedColumnName=id 335
optimisticLock = OptimisticLockType.VER- remove 304
SION 321 Restrictions.disjunction 111
optimistisches Sperren 100 Restrictions.eq 109
Optimistisches Sperren mit JSF 296 Restrictions.in 110
oracle.sql.CLOB 139 Restrictions.isEmpty 114
OracleDialect 23 Restrictions.like 110
order_updates 151 Restrictions.lt 111
OS Cache 165 Restrictions.or 111
ResultTransformer 43
P Reverse Engineering 35
rollBack 89
package 173 rowid 176
Performance 115
persist 304 S
persistence.xml 302
persistent 44 SaveOrUpdateEventListener 132
Persistenz 14 schema 172–173
Persistenz-Provider 302 Scrollable Resultsets 148
persister 175 ScrollableResults 122
persister = customPersister 321 ScrollMode.FORWARD_ONLY 122
Pessimistisches Sperren 102 Second-Level-Cache 157
pkJoinColumns 323 select-before-update 174
pojo 150 selectBeforeUpdate = false 320
polymorphism 175 SequenceGenerator 168
polymorphism = PolymorphismType.IMP- sequenceName=dbSequenceName, 325
LICIT 321 Serializable 20, 58
Polymorphismus 257 SerializableClob 139
Primärschlüssel 176 Servletfilter 96
Projections 108 Session 28
Projections.count 108 Extended Session 97
Projections.groupProperty 108 First Level Cache 87
Projections.projectionList 108 FlushMode 97
Projections.property 108 Kurze Lebensdauer 95

368
635-0.book Seite 369 Montag, 6. August 2007 12:52 12

Index

Lange Lebensdauer 97 Exception Handling 291


Lange Lebensdauer mit JPA und EJB 3 99 HibernateCallBack 290
Open-Session-in-View 96 Konfiguration 285
Session schließen 34 Problembereich Transaktionssteuerung
session.beginTransaction 89 287
session.clear 124 Propagation.MANDATORY 292
session.close 89 Propagation.NESTED 292
session.createCriteria 106 Propagation.NEVER 292
session.createQuery 32, 105 Propagation.NOT_SUPPORTED 292
session.createSQLQuery 115 Propagation.REQUIRES_NEW 292
session.delete 31, 53–54 Propagation.SUPPORTS 292
session.delete bei Beziehungen 53 Spring Templates 288
session.evict 55 Transaktionssteuerung 291
session.flush 55, 88, 124 Springframework
session.get 50, 53 @Transactional 291
session.getNamedQuery 128 AnnotationSessionFactoryBean 286
session.getStatistics 122 HibernateTransactionManager 291
session.load 307 LocalSessionFactoryBean 287
session.lock 49–50 Propagation.REQUIRED 291
session.merge 49, 52 SQL 104
session.persist 307 SQLServerDialect 23
session.refresh 55 StaleObjectStateException 100
session.save 31, 47 StandardQueryCache 162–163
session.saveOrUpdate 52 Stored Procedures 125
session.update 31, 49, 51 Struts Framework
Session-Lebensdauer 94 Exception Handling 294
session.close 34 optimistisches Sperren 293
session_factory_name 147 Struts 293
SessionFactory subselect 176
Beispiel 28 Swarm Cache 165
factory.openSession 89 SybaseDialect 23
getCurrentSession 90
HibernateSessionFactory 91 T
HibernateUtil 91
JBossTransactionManagerLookup 91 Tabellen erstellen 29
Sessionkontext 90 Table 168, 173
Set 190 targetElement = Country.class 340
setFetchMode 118 targetEntity = Invoice1.class, 331
setParameterList 110 TemporalType.DATE 329
setProjection 108 TemporalType.NONE 329
setReadOnly 108 TemporalType.TIME 329
setResultTransformer 43 TemporalType.TIMESTAMP 329
show_sql 150 ternary 233
skalare Werte 105 thread 90
some 113 Thread local 90
SortedMap 190 ThreadLocalSessionContext 90
SortedSet 190 Tomcat JNDI 154
Spring Tools
DataSourceTransactionManager 292 Eclipse 34

369
635-0.book Seite 370 Montag, 6. August 2007 12:52 12

Index

Hibernate Tools 37 X
IntelliJ 37
MyEclipse 34 XML Mapping
Netbeans 37 abstract 176
WebTool-Plugin 58 auto-import 172
transaction.auto_close_session 91, 93, batch-size 175
147 catalog 172, 174
transaction.factory_class 147 check 176
transaction.flush_before_completion 93, class 173
147 default-access 172
transaction.manager_lookup_class 147 default-cascade 172
TransactionAttributeType 308 default-lazy 172
MANDATORY 309 discriminator-value 173
NEVER 309 dynamic-insert 174
NOT_SUPPORTED 309 dynamic-update 174
REQUIRED 309 entity-name 176
REQUIRES_NEW 309 hibernate-mapping 172
SUPPORTS 309 lazy 175
Transaktionssteuerung 76, 80 mutable 173
transient 44 name 173
Treecache 166 node 176
TreeMap 190 optimistic-lock 175
TreeSet 190 package 173
type 26 persister 175
polymorphism 175
U proxy 174
rowid 176
Unidirektional 204 schema 172–173
uniqueConstraints = { ...} 322 select-before-update 174
uniqueResult 112 subselect 176
UnsupportedOperationException 115 table 173
update=false 206 where 175
UpdateTimestampsCache 162 XML Mapping 167
use_identifer_rollback 151
use_sql_comments 116, 151

V
ValidateEventListener 133
Validator 133
Vererbung 38, 257
Versionsspalte 100

W
where 175

370