Beruflich Dokumente
Kultur Dokumente
Sebastian Hennebrüder
Hibernate
Das Praxisbuch für Entwickler
635-0.book Seite 3 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
5
635-0.book Seite 6 Montag, 6. August 2007 12:52 12
Inhalt
6
635-0.book Seite 7 Montag, 6. August 2007 12:52 12
Inhalt
7
635-0.book Seite 8 Montag, 6. August 2007 12:52 12
Inhalt
8
635-0.book Seite 9 Montag, 6. August 2007 12:52 12
Inhalt
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
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.
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.
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
왘 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.
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.
Klassen erstellen
Wir benötigen eine Klasse mit Namen Honey im Package de.laliluna.example.
Unsere Klasse hat vier Attribute:
18
635-0.book Seite 19 Montag, 6. August 2007 12:52 12
왘 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.
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});
}
}
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
1.1.2 Hibernate-Konfiguration
In der Konfiguration legen wir folgende Dinge fest:
Legen Sie bitte eine Datei hibernate.cfg.xml im src-Verzeichnis an. Und jetzt die
große Frage:
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.
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
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.
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
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;
XML Mapping
Sie benötigen XML Mappings nur, wenn Sie keine Annotations verwenden.
25
635-0.book Seite 26 Montag, 6. August 2007 12:52 12
1 Einführung in Hibernate
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.
<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.
26
635-0.book Seite 27 Montag, 6. August 2007 12:52 12
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.
왘 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.
왘 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.
http://www.mysql.com/products/connector/j/
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
Wenn wir XML Mapping einsetzen, können wir folgende Zeile statt Annotati-
onConfiguration verwenden.
Legen Sie eine Datei mit dem Namen log4j.properties im src-Verzeichnis an. Wir
konfigurieren eine einfache Logausgabe in der Console.
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:
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
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.
Die Methode update lässt ein Objekt erzeugen, ändert dann den Namen und
aktualisiert das geänderte Objekt mit session.update.
Die Methode delete erzeugt gleichfalls ein Objekt und löscht es mit dem Aufruf
von session.delete sofort wieder.
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.
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.
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
Das ging jetzt sehr schnell, aber Sie müssen nicht alles auf Anhieb im Detail ver-
stehen.
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();
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.
34
635-0.book Seite 35 Montag, 6. August 2007 12:52 12
왘 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.
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
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
Hinweis
DAOs (Data Access Objects), die Sie ebenfalls mit dem Wizard erzeugen können,
besprechen wir zu einem späteren Zeitpunkt.
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.
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.
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:
285
635-0.book Seite 286 Montag, 6. August 2007 12:52 12
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-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.
<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>
287
635-0.book Seite 288 Montag, 6. August 2007 12:52 12
왘 spring.jar
왘 aspectjrt.jar
왘 spring-aspects.jar
왘 aspectjweaver.jar
288
635-0.book Seite 289 Montag, 6. August 2007 12:52 12
왘 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.
Wir übergeben der Methode execute des Templates diese frisch erstellte Imple-
mentierung zur Ausführung.
289
635-0.book Seite 290 Montag, 6. August 2007 12:52 12
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);
290
635-0.book Seite 291 Montag, 6. August 2007 12:52 12
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>
@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
propagation legt die Art der Transaktion fest. Ich habe eine Übersicht über die
Transaktionsarten zusammengestellt.
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.
292
635-0.book Seite 293 Montag, 6. August 2007 12:52 12
왘 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/)
293
635-0.book Seite 361 Montag, 6. August 2007 12:52 12
Index
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
363
635-0.book Seite 364 Montag, 6. August 2007 12:52 12
Index
364
635-0.book Seite 365 Montag, 6. August 2007 12:52 12
Index
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
367
635-0.book Seite 368 Montag, 6. August 2007 12:52 12
Index
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
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