49

Galileocomputing Hibernate

Embed Size (px)

Citation preview

Page 1: Galileocomputing Hibernate

 

Page 2: Galileocomputing Hibernate

Sebastian Hennebrüder

HibernateDas Praxisbuch für Entwickler

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

Page 3: Galileocomputing Hibernate

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 3 Montag, 6. August 2007 12:52 12

Page 4: Galileocomputing Hibernate

5

Inhalt

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

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

1.1 Erstes Hibernate-Beispiel ............................................................. 171.1.1 Projekt und Klassen erstellen .......................................... 181.1.2 Hibernate-Konfiguration ................................................. 211.1.3 Mapping ......................................................................... 231.1.4 Notwendige Bibliotheken ................................................ 271.1.5 Session-Factory erstellen ................................................. 281.1.6 Logging Konfiguration ..................................................... 291.1.7 Datenbank und Tabellen erstellen ................................... 291.1.8 Testen ............................................................................. 301.1.9 MyEclipse Tools für die Hibernate-Entwicklung ............... 341.1.10 Andere Tools für die Hibernate-Entwicklung ................... 37

1.2 Hibernate-Grundlagen ................................................................. 371.2.1 Leistungsfähige Mapping-Varianten ................................ 371.2.2 Leistungsfähige Abfragesprachen ..................................... 381.2.3 Architektur ...................................................................... 391.2.4 Lazy Initialization, ein Problembereich ............................ 401.2.5 Drei Status von Objekten ................................................ 441.2.6 Zusammenfassung ........................................................... 46

1.3 Mit Objekten arbeiten ................................................................. 471.3.1 Speichern ........................................................................ 471.3.2 Ändern ............................................................................ 481.3.3 Löschen .......................................................................... 531.3.4 Weitere Befehle .............................................................. 55

1.4 Ein komplexeres Beispiel – eine Webanwendung ......................... 561.4.1 Analyse der Anforderungen ............................................. 561.4.2 Webprojekt erstellen ....................................................... 581.4.3 Klassen erstellen ............................................................. 581.4.4 Hibernate-Konfiguration ................................................. 611.4.5 Mapping der Vererbungsklassen ...................................... 61

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

Page 5: Galileocomputing Hibernate

Inhalt

6

1.4.6 Mapping der Beziehungen .............................................. 631.4.7 Anwendungslogik ........................................................... 651.4.8 Webanwendung .............................................................. 67

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

2.1 Zeit zum Springen ........................................................................ 732.2 Best Practices und DAO ............................................................... 74

2.2.1 Data Access Objects (DAO) ............................................. 742.2.2 Anwendungsfall Buchversand .......................................... 752.2.3 Transaktionssteuerung ..................................................... 762.2.4 DAO Factory ................................................................... 772.2.5 Problem der Wiederverwendung von Geschäftslogik ....... 792.2.6 DAOs mit Generics .......................................................... 812.2.7 DAOs mit Java 1.4 .......................................................... 842.2.8 Kluge DAOs .................................................................... 86

2.3 Session und Transaktionen ........................................................... 872.3.1 Hintergrundwissen zu Sessions ........................................ 872.3.2 JTA versus JDBC-Transaktionen ....................................... 882.3.3 Konversationen und Session-Lebensdauer ....................... 942.3.4 Konkurrierender Zugriff ................................................... 100

2.4 Daten abfragen ............................................................................ 1032.4.1 Vergleich von HQL, Criteria und SQL .............................. 1032.4.2 Abfragen mit HQL und Criteria ........................................ 1052.4.3 Where-Bedingungen ....................................................... 1092.4.4 SQL-basierte Abfragen .................................................... 114

2.5 Performance ................................................................................ 1152.5.1 Einleitung ....................................................................... 1152.5.2 Debugging der Abfragen ................................................. 1152.5.3 Effizientes Iterieren durch Beziehungen ........................... 1172.5.4 Effiziente Abfragen bei Beziehungen ............................... 1182.5.5 Separate Klassen für Berichte .......................................... 1182.5.6 Verwendung des Caches ................................................. 1192.5.7 Read-Only-Mapping ....................................................... 1202.5.8 Verzicht auf Beziehungen ................................................ 1202.5.9 Iterieren durch große Datenmengen ................................ 1212.5.10 Schreiben von großen Datenmengen ............................... 1222.5.11 Verwendung von Stored Procedures ................................ 1252.5.12 Lazy Loading für Attribute ............................................... 125

2.6 Fortgeschrittene Möglichkeiten ................................................... 1262.6.1 Bytecode-Instrumentation ............................................... 126

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

Page 6: Galileocomputing Hibernate

Inhalt

7

2.6.2 Named Queries ............................................................... 1282.6.3 Dynamic-update, dynamic insert ..................................... 1292.6.4 Eigene Types definieren .................................................. 1302.6.5 Eigene Entity-Persister erstellen ...................................... 1302.6.6 Interceptor ...................................................................... 1312.6.7 Events ............................................................................. 1322.6.8 Mapping auf XML statt Klassen ....................................... 1332.6.9 Validieren von Attributen ................................................ 1332.6.10 Volltextindizierung mit Lucene ........................................ 1342.6.11 LOB mit Oracle und PostgreSQL ..................................... 134

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

3.1 Einstellungen ............................................................................... 1433.1.1 Konfiguration mit Java .................................................... 1443.1.2 Datenbankverbindung ..................................................... 1443.1.3 Session- und Transaktionsverhalten ................................. 1473.1.4 JDBC-Einstellungen ......................................................... 1483.1.5 Cache-Einstellungen ........................................................ 1493.1.6 Weitere Einstellungen ..................................................... 150

3.2 Connection Pool .......................................................................... 1523.2.1 Hibernate Connection Pool ............................................. 1523.2.2 C3P0 ............................................................................... 1533.2.3 DBCP .............................................................................. 1533.2.4 JNDI ............................................................................... 154

3.3 Caches ......................................................................................... 1573.3.1 Einleitung ....................................................................... 1573.3.2 Einsatz des Caches .......................................................... 1603.3.3 Einsatz des Query Caches ................................................ 1623.3.4 Testen der Cache-Implementierungen ............................. 1633.3.5 Wie viel Performance bringt ein Cache? .......................... 1643.3.6 EH Cache ........................................................................ 1643.3.7 OS Cache ........................................................................ 1653.3.8 Swarm Cache .................................................................. 1653.3.9 JBoss TreeCache .............................................................. 166

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

4.1 Mapping mit Annotation oder XML ............................................. 1674.2 Annotation Mapping ................................................................... 169

4.2.1 Was sind Annotations? .................................................... 169

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

Page 7: Galileocomputing Hibernate

Inhalt

8

4.2.2 Felder-, Methoden- und Klassen-Annotations ................. 1704.2.3 Voraussetzungen ............................................................. 1714.2.4 Weitere Informationen .................................................... 171

4.3 XML Mapping ............................................................................. 1714.3.1 Übersicht ........................................................................ 1714.3.2 Class Mapping ................................................................. 1734.3.3 Weitere XML Tags ........................................................... 176

4.4 Mapping von Primärschlüsseln ..................................................... 1764.4.1 Natürliche versus künstliche Ids ...................................... 1774.4.2 Quellcode ....................................................................... 1784.4.3 Id-Strategie Assigned ...................................................... 1784.4.4 Id-Strategie automatisch ................................................. 1794.4.5 Weitere Annotation-Id-Strategien ................................... 1794.4.6 XML-Id-Strategien .......................................................... 1804.4.7 Composite Id .................................................................. 183

4.5 Mapping von Beziehungen .......................................................... 1874.5.1 Einführung ...................................................................... 1874.5.2 List, Set, Map oder Array ................................................. 1884.5.3 Uni- und bidirektionale Beziehungen .............................. 2044.5.4 Cascading ........................................................................ 2074.5.5 Hinweise zu den Beispielen ............................................. 2094.5.6 1:1 Beziehung ................................................................. 2104.5.7 1:n-Beziehung ................................................................. 2164.5.8 m:n-Beziehung ................................................................ 2274.5.9 1:n:1-Beziehung .............................................................. 2334.5.10 Rekursive Beziehung ....................................................... 2364.5.11 Typisierte Beziehung (XML) ............................................. 2384.5.12 Typisierte Beziehung (Annotation Workaround) .............. 241

4.6 Mapping von Komponenten ........................................................ 2434.6.1 Einführung ...................................................................... 2434.6.2 Eine Komponente ........................................................... 2444.6.3 Eine Liste von Komponenten ........................................... 2474.6.4 Ein Set von Komponenten ............................................... 2494.6.5 1:n:1-Komponente .......................................................... 2514.6.6 Zusammengesetzte Primärschlüssel als Komponente ....... 254

4.7 Vererbung ................................................................................... 2574.7.1 Einführung ...................................................................... 2574.7.2 Auswahl des Mapping-Ansatzes ...................................... 2594.7.3 Klassenhierarchie in einer Tabelle .................................... 2624.7.4 Klassenhierarchie mit einer Tabelle pro Klasse ................. 266

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

Page 8: Galileocomputing Hibernate

Inhalt

9

4.7.5 Klassenhierarchie mit einer Tabelle pro Klasse und Discriminator .................................................................. 271

4.7.6 Vermischen zweier Ansätze ............................................. 2744.7.7 Klassenhierarchie mit einer Tabelle für jede

konkrete Klasse ............................................................... 2744.7.8 Klassenhierarchie mit einer Tabelle pro Unterklasse ......... 2794.7.9 Klassenhierarchie mit einer Tabelle pro Unterklasse ......... 281

4.8 Weitere Mappings ....................................................................... 284

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

5.1 Hibernate und Spring ................................................................... 2855.1.1 Konfiguration .................................................................. 2855.1.2 Verwendung des Spring Templates .................................. 2885.1.3 Alternative zum Spring Template ..................................... 2905.1.4 Transaktionssteuerung ..................................................... 291

5.2 Hibernate und Struts .................................................................... 2935.2.1 Optimistisches Sperren .................................................... 2935.2.2 Zentrales Exception Handling .......................................... 294

5.3 Hibernate und JSF/MyFaces ......................................................... 2955.3.1 Implementierung ............................................................ 2955.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 .................................................. 3026.1.1 Persistenz-Provider ......................................................... 3026.1.2 Gemappte Klassen .......................................................... 3036.1.3 Mit Objekten arbeiten .................................................... 3036.1.4 Hibernate in JPA nutzen .................................................. 3056.1.5 Exception Handling ......................................................... 305

6.2 Unterschiede zwischen Hibernate und JPA ................................... 3076.3 EJB 3 ........................................................................................... 307

6.3.1 Deployment nach Glassfish ............................................. 3106.3.2 Deployment nach JBoss ................................................... 311

6.4 Dialoge mit lang lebender Session ............................................... 313

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

Page 9: Galileocomputing Hibernate

Inhalt

10

Anhang............................................................................................ 317

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

B Hilfreiche Tools ...................................................................................... 357C Literaturverzeichnis ................................................................................ 359

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

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

Page 10: Galileocomputing Hibernate

17

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 startenwir 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 dasdarzustellen, 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.

Abbildung 1.1 Ein Klassendiagramm

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

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

Honey-id : Integer-name : String-honey : Honey

Beehoney

bees *

1

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

Page 11: Galileocomputing Hibernate

18

Einführung in Hibernate1

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 Bienegespeichert werden

� Hibernate-Libraries konfigurieren

� Hibernate konfigurieren mitsamt Datenquelle

� Quellcode schreiben, der unsere Klassen verwendet

1.1.1 Projekt und Klassen erstellen

Java-Projekt erstellen

Erstellen Sie in Ihrer Entwicklungsumgebung ein neues Java-Projekt. Ich habeEclipse 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

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

+ id int4 Nullable = falsename varchar(255) Nullable = true

# honey_id int4 Nullable = true

bee+ id int4 Nullable = false

name varchar(255) Nullable = truetaste varchar(255) Nullable = true

honey

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

Page 12: Galileocomputing Hibernate

19

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) {

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

Page 13: Galileocomputing Hibernate

20

Einführung in Hibernate1

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 sindMerkmale der Klasse.

Hier gilt der gleiche »Bitte nicht vergessen«-Hinweis, den ich bei der vorherigenKlasse 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() { }

Bitte nicht vergessenDamit 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-VersionIch 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 @.

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

Page 14: Galileocomputing Hibernate

21

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 diegroß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 mitAnnotation oder XML«, im Detail. Hier treffen wir einfach eine schnelle Entschei-dung.

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

Page 15: Galileocomputing Hibernate

22

Einführung in Hibernate1

Ich zeige Ihnen jetzt eine Annotation-Version für PostgreSQL und gebe dann dieHinweise, was man ändern muss, um die Konfiguration für andere Datenbankenoder 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ßendlegen wir mit der Einstellung dialect fest, in welchen SQL-Dialekt HibernateAbfragen übersetzt.

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

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

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

Page 16: Galileocomputing Hibernate

23

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 Downloadvon 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>-Tagsersetzen.

<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 Attributeiner Klasse zugeordnet ist. Wie oben bereits erwähnt, gibt es zwei Möglichkei-ten: Annotation und XML.

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

Page 17: Galileocomputing Hibernate

24

Einführung in Hibernate1

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. DenPrimärschlüssel kennzeichnen wir mit @Id. Unser Primärschlüssel verwendeteine Datenbanksequenz. Diese muss mit Hilfe von @SequenceGenerator definiertwerden, 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. Daherhabe 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 Namenfestlegen, 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;

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

Page 18: Galileocomputing Hibernate

25

Erstes Hibernate-Beispiel 1.1

import javax.persistence.SequenceGenerator;@Entitypublic 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>

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

Page 19: Galileocomputing Hibernate

26

Einführung in Hibernate1

<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 Tabellenspaltenzugeordnet. 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 wirHibernate 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 Beziehungaus Sicht der Klasse Bee beschrieben. Die assoziierte Klasse Honey müssen wirnicht 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 einzigeJava-Klasse java.util.Date.

Hibernate müsste raten, welchen Typen Sie meinen. Daher empfehle ich, immer dieHibernate-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.

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

Page 20: Galileocomputing Hibernate

27

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 SieAnnotations 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 allebenö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

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

Page 21: Galileocomputing Hibernate

28

Einführung in Hibernate1

DatenbanktreiberNatürlich ist auch ein JDBC-Datenbanktreiber notwendig. Die entsprechendeBibliothek muss noch besorgt werden. Für PostgreSQL bekommt man diesen aufhttp://jdbc.postgresql.org. Der JDBC 3-Treiber ist in Ordnung, wenn Sie Java1.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 dieseKlasse eine Fabrik, mit der wir Hibernate-Sessions erzeugen können, wannimmer 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 Datenbankabfragen.

Die Session-Factory initialisiert auch die Hibernate-Konfiguration. Wir müssenwieder 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; }}

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

Page 22: Galileocomputing Hibernate

29

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 auchXML 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 Bibliothekhinzugefügt. Log4j erwartet eine Konfigurationsdatei im Hauptverzeichnis, sonstwerden 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. Wirkonfigurieren eine einfache Logausgabe in der Console.

### direct log messages to stdout ###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n# Achtung, die vorherige Zeile wird versehendlich umgebrochenlog4j.rootLogger=debug, stdoutlog4j.logger.org.hibernate=info#log4j.logger.org.hibernate=debug### log just the SQLlog4j.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 Hibernatebei 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 sichdaher nur für die Entwicklung. Alternativ kann man die Einstellung update ver-wenden. Hibernate versucht dann, die Tabellen nur bei Bedarf zu erzeugen bzw.

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

Page 23: Galileocomputing Hibernate

30

Einführung in Hibernate1

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

1.1.8 Testen

Wir werden eine einfache Klasse erstellen, die unser Mapping verwendet, zudemDaten erstellt, löscht und abfragt. Ich gebe Ihnen jetzt noch ein paar Hinweiseund 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();

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

Page 24: Galileocomputing Hibernate

31

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 denAufruf 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 undaktualisiert 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 Aufrufvon session.delete sofort wieder.

private static void delete() { Honey honey = createHoney(); Transaction tx = null; Session session = InitSessionFactory.getInstance() .getCurrentSession();

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

Page 25: Galileocomputing Hibernate

32

Einführung in Hibernate1

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 QueryLanguage (HQL) abgefragt werden. Die Abfrage wird wiederum mit session.crea-teQuery erzeugt. Diesmal rufen wir aber die Methode list auf, da wir ein Ergebniserwarten.

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

Page 26: Galileocomputing Hibernate

33

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.

Unser Quellcode sieht also gewöhnlich einfach so aus:

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

Das sollten Sie gelernt habenErstellen einer Klasse, die gemappt werden soll. Wichtig waren ein parameterloserDefault-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 einerException.

� Nach einer Exception ist die aktuelle Session unbrauchbar. Wir müssen dieseschließ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 Methodesession.close() aufrufen.

� In einer normalen Anwendung reicht uns eine Stelle aus, die Transaktionenzurückrollt und die Session – wenn erforderlich – schließt.

� Das könnten wir in einem Exception Handler von Struts, einem Interceptor vonMyFaces oder in einem Servletfilter vornehmen.

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

Page 27: Galileocomputing Hibernate

34

Einführung in Hibernate1

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

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/. Ichverwende es für die Entwicklung von Webanwendungen. Es bietet Unterstüt-zung für Spring, Hibernate, EJB, Struts, MyFaces und ist gewöhnlich auf einemrecht aktuellen Stand.

Hibernate-Unterstützung aktivieren

Mit MyEclipse können Sie Webprojekte direkt anlegen. Klickt man im PackageView 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

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, stelltdas für uns sicher. Wir brauchen daher nicht explizit ein session.close aufzurufen.

Deployment im JBoss Application-ServerWenn 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 unerwartetemVerhalten in den Beispielen, da ich in der Hibernate-Konfiguration festlege, wie sichdie Session verhalten soll, und innerhalb vom JBoss dies teilweise ignoriert wird.

Entweder verwenden Sie vorerst den Tomcat Application-Server bzw. eine andereServlet Engine oder Sie werfen bereits jetzt einen Blick in die Abschnitte 2.3.2 und5.4, »JTA versus JDBC Transaktionen«.

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

Page 28: Galileocomputing Hibernate

35

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 konfigurierteine 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 Klassenauf Basis einer existierenden Datenbank. MyEclipse integriert solche Funktionenelegant in Eclipse.

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

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

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

Page 29: Galileocomputing Hibernate

36

Einführung in Hibernate1

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.

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

Page 30: Galileocomputing Hibernate

37

Hibernate-Grundlagen 1.2

Abbildung 1.7 Die Auswahl der Tabellen

1.1.10 Andere Tools für die Hibernate-Entwicklung

Die Entwicklungsumgebungen IntelliJ und Netbeans verfügen von Haus aus überHibernate-Tools. Auf den Webseiten von Hibernate können Sie sich ferner dieHibernate 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 eineganze 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-

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

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

Page 31: Galileocomputing Hibernate

285

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 Sieauf der Seite http://www.springframework.org/ herunterladen. Dieses Kapitelsetzt 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 vonihnen 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 dasTransaktionshandling anders konfigurieren. Das werde ich an entsprechenderStelle erläutern.

5.1.1 Konfiguration

Sie haben drei Möglichkeiten der Konfiguration von Hibernate, wenn Sie Springverwenden:

� 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 demMyEclipse-Plugin:

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

Page 32: Galileocomputing Hibernate

286

Integration anderer Technologien5

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 dieseverwenden, sonst funktioniert die Integration nicht ordentlich und es könnenConnection 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 zurDatenquelle oder zum Verhalten der Session.

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

Page 33: Galileocomputing Hibernate

287

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>

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

<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.

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

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

Page 34: Galileocomputing Hibernate

288

Integration anderer Technologien5

5.1.2 Verwendung des Spring Templates

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

� spring.jar

� aspectjrt.jar

� spring-aspects.jar

� aspectjweaver.jar

Warum keine Hibernate-Session-Factory?Es wäre möglich, statt der Spring-Session-Factory unsere Hibernate-Session-Factoryaus den bisherigen Beispielen zu verwenden. Dann müssten wir auch eins der inAbschnitt 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 eineJDBC-Transaktion einschließen. Auf diese elegante Möglichkeit verzichten wir, wennwir die Hibernate-Session-Factory verwenden.

Ich empfehle, lieber die Möglichkeiten von Spring zu verwenden. Dabei müssen Sieaber auf die Nutzung der Hibernate-Transaktionssteuerung verzichten, sonst hatSpring erhebliche Schwierigkeiten, Datenbankverbindungen und Hibernate-Sessionsfreizugeben. Verwenden Sie also auf keinen Fall session.beginTransaction(), wenn Siesich für den »Spring Weg« entscheiden.

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

Page 35: Galileocomputing Hibernate

289

Hibernate und Spring 5.1

Spring bietet für unterschiedliche Persistenztechnologien ein Template an, dasdie 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 guterAnsatz, um ein einheitliches Verhalten und eine globale Transaktionssteuerungzu 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 stehendeBeispiel zeigt die Verwendung. Sie lesen den Quellcode am besten von innennach 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 desInterfaces 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, dieAusführung des Hibernate-Codes zu kapseln, Ausnahmen umzuwandeln undsicherzustellen, dass, wenn eine Exception im Hibernate-Code auftritt, die Trans-

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

Page 36: Galileocomputing Hibernate

290

Integration anderer Technologien5

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

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

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

template.save(hedgehog);

5.1.3 Alternative zum Spring Template

Es gibt sicherlich schöneren Quellcode als das oben gezeigte Template. Ichmö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);}

Problembereich des Hibernate TemplatesIch rate dringend davon ab, die unterschiedlichen find-Methoden des HibernateTemplates zu verwenden. Das Template hat globale Einstellung für die maximaleAnzahl von Zeilen, die eine Abfrage zurückliefert, zum Verhalten in Bezug auf denCache 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, ineinem HibernateCallBack.

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

Page 37: Galileocomputing Hibernate

291

Hibernate und Spring 5.1

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

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 diesemBeispiel 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 findenSie in der Spring-Dokumentation. Die Konfiguration hängt immer vom Applica-tion-Server ab.

Innerhalb der Anwendung sind Transaktionen leicht zu integrieren. Wir müssennur die Annotation @Transactional vor eine Methode schreiben. Spring wirddann vor der Methode die Transaktion starten und nach der Methode ein commitaufrufen.

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

Exception HandlingDie 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. Derzweite 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 istund weniger Schreibarbeit erfordert.

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

Page 38: Galileocomputing Hibernate

292

Integration anderer Technologien5

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

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

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.

Tipp: Transaktionskonfiguration auf KlassenebeneSie 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 Methodeanders verhalten soll, so können Sie dort einfach eine weitere Annotation einfügenund den Vorgabewert überschreiben.

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

Page 39: Galileocomputing Hibernate

293

Hibernate und Struts 5.2

5.2 Hibernate und Struts

Ich habe eine kleine Beispielanwendung geschrieben, die Sie auf der Webseitezum Buch (http://www.galileocomputing.de/978) finden. Diese Anwendungorientiert 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 Benutzereinen Datensatz bereits geändert hat, seitdem die Daten geladen worden sind.

Transaktionen ohne AnnotationDie Verwendung von Annotations für die Konfiguration ist meiner Meinung nacheine 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 steuernoder über die Spring-Konfigurationsdatei festlegen. Mehr Informationen dazu findenSie in der Spring-Dokumentation.

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

Page 40: Galileocomputing Hibernate

361

Index

<array> 203<bag> 195<cache> 160<collection-id> 202<component> 246<composite-element> 248<composite-id> 187, 239, 256<discriminator> 264<formula> 239<generator class=foreign> 216<idbag> 202<join table=..> 272<join> 227<joined-subclass> 268<list> 201<many-to-any> 280<many-to-many> 226, 229<many-to-one> 211, 220<map> 198<map-key> 198<meta-value> 280<one-to-one> 214<parent> 246<primitive-array> 204<set 218<set> 193, 218<subclass> 264, 272<union-subclass> 277<version 101@AccessType 345@AttributeOverride 330@Basic 328@BatchSize 117, 342@Cache 347@Cascade 338@Check 347@CollectionOfElements 203, 247, 252,

334@Column 328@ColumnResult 355@DiscriminatorColumn 263, 344@DiscriminatorFormula 345@DiscriminatorValue 344@Embeddable 245, 248, 334@Embedded 245, 333

@EmbeddedId 184, 325@Entity 24, 319@EntityResult 354@Enumerated 329@Fetch 338@FieldResult 354@Filter 348@FilterDef 349@Filters 348@Formula 331@GeneratedValue 24, 324@GenericGenerator 327@Id 24, 324@IdClass 186, 325@Index 322@IndexColumn 201, 247, 337@Indexed Hinweis 222@Inheritance 263, 267, 343@JoinColumn 24, 335@JoinColumns 335@JoinTable 226, 228, 336@LazyCollection 342@LazyToOne 343@Length 133@Lob 135, 329@ManyToMany 228, 333@ManyToOne 24, 220, 332@MapKey 198, 339@MapKeyManyToMany 234@MappedSuperclass 282, 345@NamedNativeQueries 129, 352@NamedNativeQuery 353@NamedQueries 128, 350@NamedQuery 128, 350–351@NotFound 340@OnDelete 340@OneToMany 24, 218, 332@OneToOne 210, 331@OrderBy [email protected]

AccessType 345BatchSize 342Cache 347Cascade 338Check 347

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

Page 41: Galileocomputing Hibernate

362

Index

CollectionOfElements 334DiscriminatorFormula 345Entity 319Fetch 338Filter 348FilterDef 349Filters 348Formula 331GenericGenerator 327Index 322IndexColumn 337LazyCollection 342LazyToOne 343MapKey 339NamedQueries 350NamedQuery 351OnDelete 340OrderBy 341ParamDef 349Parameter 347Parent 334Table 322Type 346TypeDef 347TypeDefs 346Where 341

@org.hibernate.NotFound 340@ParamDef 349@Parameter 347@Parent 245, 334@PersistenceContext 308@PrimaryKeyJoinColumn 216, 336@PrimaryKeyJoinColumns 337@QueryHint 128, 351@SecondaryTable 323@SequenceGenerator 24, 325@SqlResultSetMapping 129, 354@SqlResultSetMappings 353@Table 322@TableGenerator 326@Target 170@Temporal 329@TransactionAttribute 308@Transient 328@Type 346@TypeDefs 130, 346–347@UniqueConstraint 323@Version 101, 330@Where 341

A

Abfragen@NamedQueries 128@NamedQuery 128AliasToBeanResultTransformer 109all 113any 113createAlias 111DetachedCriteria 113executeUpdate 115exists 113gtAll 113gtSome 114in 113left join fetch 118MatchMode.START 110Parameter 112Property.forName 113Restrictions.disjunction 111Restrictions.eq 109Restrictions.in 110Restrictions.isEmpty 114Restrictions.like 110Restrictions.lt 111Restrictions.or 111setFetchMode 118setParameterList 110setReadOnly 108some 113uniqueResult 112Where-Bedingung mit Beziehungen 111

abstract 176action = NotFoundAction.IGNORE 340after_statement 146after_transaction 146Aggregation 244AliasToBeanResultTransformer 109all 113allocationSize 124, 325Annotation 167AnnotationConfiguration 29Annotation-Nachteile 169Annotations an Felder, Methoden und

Klassen 170AnnotationSessionFactoryBean 286Annotation-Vorteile 168any 113appliesTo = tableName 322

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

Page 42: Galileocomputing Hibernate

363

Index

ArchitekturGeschäftslogik 39Persistenz Layer 39Webanwendung 39

Array 190ArrayList 189–190Assoziation 17, 37, 188, 244ASTQueryTranslatorFactory 152auto-import 172

B

Bag 189batch-size 175Bibliotheken 27Bidirektional 205BinaryType 136BLOB 134BLOB Lazy Loading 126Blob-Felder 149BlobType 137bytea 136Bytecode-Instrumentation 126–127

C

C3P0 153c3p0.* 145Cache

Cache 157Cache deaktivieren 149Cache Modus 159Cache verwenden 161nonstrict-read-write 159Query Cache 162read-only 159read-write 159transactional 159–160

cache.provider_class 149cache.query_cache_factory 149cache.region_prefix 150cache.use_minimal_puts 149cache.use_query_cache 149cache.use_second_level_cache 149cache.use_structured_entries 150CacheConcurrencyStrategy 348CacheModeType 351Cache-Regionen 150Cascading 48, 207

all 208all-delete-orphan 208CascadeType 338CascadeType.ALL 208CascadeType.DELETE_ORPHAN 208CascadeType.REFRESH 207CascadeType.REMOVE 207delete 208delete-orphan 208evict 208Fehlerpotenzial 209lock 208MERGE 208PERSIST 208persist 208REFRESH 208refresh 208REMOVE 208replicate 208save-update 208

catalog 172, 174catalog = catalogName 322cglib.use_reflection_optimizer 144, 152check 176class 173ClassicQueryTranslatorFactory 152clause = deleted=false 341clear() 124CLOB 126, 134CLOB Lazy Loading 126Clustering 149Collection 189Component Mapping 243Configuration 29Connection Pool

Connection Pool 152Connection Pool mit Jboss 156Connection Pool mit Tomcat 154

connection.autocommit 146connection.datasource 145connection.driver_class 145connection.eineEinstellung 146connection.isolation 146connection.password 145connection.provider_class 146connection.release_mode 146connection.url 23, 145connection.username 145context.xml 154

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

Page 43: Galileocomputing Hibernate

364

Index

createAlias 111createSQLQuery 115Criteria Queries 39Criteria.DISTINCT_ROOT_ENTITY 43Criteria-Abfragen 104current_session_context 33current_session_context_class 147

D

DAODAO Factory 77Dao mit SessionFactory vs Session 78DAOs mit Generics 81DAOs mit Java 1.4 84Data Access Objects (DAO) 74Kluge DAO 86

Datenbanktreiber 28DBCP 153Debugging 115default_batch_fetch_size 118, 151default_catalog 151default_entity_mode 150default_schema 150default-access 172default-cascade 172default-lazy 172DefaultLoadEventListener 132DerbyDialect 23detached 44DetachedCriteria 113dialect 22, 144Discriminator Column 38discriminatorType 263discriminatorType = Discriminator-

Type.STRING 344DiscriminatorType.CHAR 344DiscriminatorType.INTEGER 344DiscriminatorType.STRING 263, 344discriminator-value 173dom4j 150dynamic insert 129, 174, 320dynamic update 101, 129, 174, 320dynamic-map 150

E

EH Cache 164EJB 3 301

Entity 167, 173Entity-Manager 301EntityManagerFactory 303entity-name 176EnumType.ORDINAL 329EnumType.STRING 329EventListener 132Eventsystem 132Exception 30, 89

LazyInitializationException 41, 94NonUniqueObjectException 50StaleObjectStateException 51

Exception Handling 68Exception Handling in JPA 305Exception Handling mit JSF (MyFaces)

296Exception Handling mit Spring 292Exception Handling mit Struts 294Try und Catch 33Try und Catch in Webanwendung 68

executeUpdate 115exists 113explicit 175

F

fetch=FetchType.EAGER 331FetchMode.JOIN 339FetchMode.SELECT 339FetchMode.SUBSELECT 339find 304First Level Cache 87First-Level-Cache 157flush() 124FlushMode 97flushMode 351FlushModeType.AUTO 351Foreign Key Constraint 205format_sql 116Fremdschlüsselspalte 24

G

generate_statistics 151GeneratedValue 168GenerationType 168GenerationType.AUTO 324GenerationType.IDENTITY 324GenerationType.SEQUENCE 324

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

Page 44: Galileocomputing Hibernate

365

Index

GenerationType.TABLE 324Generics 20getReference 307Glassfish 310gtAll 113gtSome 114

H

HashMap 190HashSet 190hbm2ddl.auto 22, 150Hibernate Validator 133hibernate.cfg.xml 143hibernate.hbm2ddl.auto 29Hibernate.initialize 43hibernate.jdbc.use_streams_for_binary

144hibernate.properties 143hibernate3.jar 27hibernate-annotations.jar 27HibernateCallBack 290hibernate-mapping 172HibernateServiceBean 298Hibernate-Typen 26hints = {@QueryHint(...)} 350HQL 32, 38, 103HQL-, Criteria- und SQL-Vergleich 103HSQLDialect 23

I

Id 168<composite-id> 185<generator class=native> 179<id> 182<key-property> 185@EmbeddedId 184@IdClass 186assigned 178, 181Composite Id 183equals 183foreign 182GenerationType.AUTO 179GenerationType.IDENTITY 180GenerationType.SEQUENCE 179GenerationType.TABLE 180generator class 182GenericGenerator 180

guid 181hashCode 183hilo 181Id 176identity 181increment 182künstlicher Schlüssel 178MultipleHiLoPerTableGenerator 182native 181Natürliche Schlüssel 177select 181seqhilo 181sequence 181Trigger 181unsaved-value 182uuid 182

implicit 175in 113indexes 322Inheritance 257InheritanceType.JOINED 267, 343InheritanceType.SINGLE_TABLE 263,

343InheritanceType.TABLE_PER_CLASS 275,

343initialValue=1 325inner join 106insert=false 206InstrumentTask 127Interceptor 131inverse 206inverseJoinColumns 228, 336Inversion of Control 308

J

Java Persistence API 301JavaServer Faces 295

Exception Handling 296javax.persistence. 167JBoss Application-Server 34JBoss Cache 166JBoss JPA 311JBoss Treecache 166jdbc.batch_size 148jdbc.batch_versioned_data 148jdbc.factory_class 148jdbc.fetch_size 148jdbc.use_get_generated_keys 149

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

Page 45: Galileocomputing Hibernate

366

Index

jdbc.use_scrollable_resultset 148jdbc.use_streams_for_binary 149JDBCTransactionFactory 90JDBC-Transaktionen 88Jgroups 165JNDI 154JNDI Connection Pool 154jndi.class 145jndi.eineEinstellung 145jndi.url 145Join 106joinColumns 228, 336JPA 301JPA und EJB3

@TransactionAttribute 308Entity-Manager 301EntityManager 304EntityManagerFactory 303–304find 304getReference 307Glassfish 310Inversion of Control 308JBoss 311JPA 301JPA – Java-Persistenz-API 171persist 304persistence.xml 302Persistenz-Provider 302remove 304Toplink 301TransactionAttributeType 308

MANDATORY 309NEVER 309NOT_SUPPORTED 309REQUIRED 309REQUIRES_NEW 309SUPPORTS 309

JTA – Java Transaction API 88jta.UserTransaction 148

K

Komponenten Mapping 243Komposition 38, 244Konfiguration

Konfiguration mit Java 144Konkurrierender Zugriff 100Konstruktor 20, 58Konversationen 94

L

lazy 175Lazy Initialization 40, 47LazyCollectionOption.EXTRA 342LazyCollectionOption.FALSE 342LazyCollectionOption.TRUE 342Lazy-Fetching 42LazyInitializationException 41, 95LazyToOneOption.FALSE 343LazyToOneOption.NO_PROXY 343LazyToOneOption.PROXY 343left join fetch 43, 118List 190LoadEventListener 132LOB (Large Object) 134LocalSessionFactoryBean 287LockMode.NONE 51LockMode.READ 51LockMode.UPGRADE 51, 103Logging

log4j 29log4j.logger.org.hibernate.cache 116log4j.logger.org.hibernate.id 116log4j.logger.org.hibernate.SQL 116log4j.logger.org.hibernate.type 116

Löschen von Daten 53Lucene 134

M

Map 190mappedBy 206Mapping

Beziehungen 187Komponenten 243Vererbung 257Vor- und Nachteile 190

Mapping von Beziehungen<array> 203<bag> 195<collection-id> 202<idbag> 202<join> 227<list> 201<many-to-many> 226, 229<many-to-one> 211, 220<map> 198<map-key> 198

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

Page 46: Galileocomputing Hibernate

367

Index

<one-to-one> 214<primitive-array> 204<set> 193, 218@AttributeOverrides 197@CollectionOfElements 197, 203@Column 197@IndexColumn 201, 203@JoinColumn 192, 194, 197@JoinTable 197, 226, 228@ManyToMany 228@ManyToOne 220@MapKey 198@MapKeyManyToMany 234@OneToMany 192, 194, 201, 218@OneToOne 210@PrimaryKeyJoinColumn 216@Sort 1941:1 Beziehung 2101:n-Beziehung 216Array 191Bag 190, 195bidirektional 205Fehlerpotenzial manyToMany 230Foreign Key Constraint 205insert=false 206inverse 206inverseJoinColumns 228joinColumns 228List 191m:n-Beziehung 227Map 191, 196mappedBy 206property-ref 214rekursive Beziehung 236Set 190, 192SortedMap 191SortedSet 190, 193strategy = foreign 216unidirektional 204update=false 206Verwalten der Beziehung 206Vor- und Nachteile 190

Mapping von Komponenten<component> 246<composite-element> 248<composite-id> 256<parent> 246@CollectionOfElements 247@Embeddable 245

@Embedded 245@Parent 245einfache Komponente 244Fehlerpotenzial bei non-indexed 249Komponenten 243Liste von Komponenten 247Set von Komponenten 249zusammengesetzte Primärschlüssel 254

Mapping von Vererbung<discriminator> 264<join table=..> 272<joined-subclass> 268<many-to-any> 280<meta-value> 280<subclass> 264, 272<union-subclass> 277@DiscriminatorColumn 263@Inheritance 263@MappedSuperclass 282Auswahl des Mapping-Ansatzes 259Discriminator Column 38discriminatorType 263DiscriminatorType.STRING 263InheritanceType.JOINED 267InheritanceType.SINGLE_TABLE 263InheritanceType.TABLE_PER_CLASS 275Klassenhierarchie in einer Tabelle 262Klassenhierarchie mit einer Tabelle für jede

konkrete Klasse 274Klassenhierarchie mit einer Tabelle pro

Klasse 266Klassenhierarchie mit einer Tabelle pro

Klasse + Discriminator 271Klassenhierarchie mit einer Tabelle pro

Unterklasse 279, 281Vererbung 257

MatchMode.START 110max_fetch_depth 151mutable 173mutable = true 320MyFaces 295MySQL5Dialect 23

N

name 173Named Queries 128node 176NonUniqueObjectException 50, 95

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

Page 47: Galileocomputing Hibernate

368

Index

NotFoundAction.EXCEPTION 340NotFoundAction.IGNORE 340

O

Object-Relational-Mapping 13oid 136on_close 146OnDeleteAction.CASCADE 340OnDeleteAction.NO_ACTION 340Open-Session-in-View 42, 96optimisticLock 101, 175OptimisticLockType.ALL 101, 321OptimisticLockType.DIRTY 102, 321OptimisticLockType.VERSION 321Optimistisches Sperren

optimisticLock = OptimisticLockType.VER-SION 321

optimistisches Sperren 100Optimistisches Sperren mit JSF 296

oracle.sql.CLOB 139OracleDialect 23order_updates 151OS Cache 165

P

package 173Performance 115persist 304persistence.xml 302persistent 44Persistenz 14Persistenz-Provider 302persister 175persister = customPersister 321Pessimistisches Sperren 102pkJoinColumns 323pojo 150polymorphism 175polymorphism = PolymorphismType.IMP-

LICIT 321Polymorphismus 257Primärschlüssel 176Projections 108

Projections.count 108Projections.groupProperty 108Projections.projectionList 108Projections.property 108

Property.forName 113PropertyAccessor 172, 183property-ref 214proxy 174

Q

query = fromComputerBook), 350Query Cache 163query.factory_class 152query.substitutions 152

R

Read-Only-Mapping 120referencedColumnName=id 335remove 304Restrictions.disjunction 111Restrictions.eq 109Restrictions.in 110Restrictions.isEmpty 114Restrictions.like 110Restrictions.lt 111Restrictions.or 111ResultTransformer 43Reverse Engineering 35rollBack 89rowid 176

S

SaveOrUpdateEventListener 132schema 172–173Scrollable Resultsets 148ScrollableResults 122ScrollMode.FORWARD_ONLY 122Second-Level-Cache 157select-before-update 174selectBeforeUpdate = false 320SequenceGenerator 168sequenceName=dbSequenceName, 325Serializable 20, 58SerializableClob 139Servletfilter 96Session 28

Extended Session 97First Level Cache 87FlushMode 97Kurze Lebensdauer 95

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

Page 48: Galileocomputing Hibernate

369

Index

Lange Lebensdauer 97Lange Lebensdauer mit JPA und EJB 3 99Open-Session-in-View 96Session schließen 34session.beginTransaction 89session.clear 124session.close 89session.createCriteria 106session.createQuery 32, 105session.createSQLQuery 115session.delete 31, 53–54session.delete bei Beziehungen 53session.evict 55session.flush 55, 88, 124session.get 50, 53session.getNamedQuery 128session.getStatistics 122session.load 307session.lock 49–50session.merge 49, 52session.persist 307session.refresh 55session.save 31, 47session.saveOrUpdate 52session.update 31, 49, 51Session-Lebensdauer 94

session.close 34session_factory_name 147SessionFactory

Beispiel 28factory.openSession 89getCurrentSession 90HibernateSessionFactory 91HibernateUtil 91JBossTransactionManagerLookup 91

Sessionkontext 90Set 190setFetchMode 118setParameterList 110setProjection 108setReadOnly 108setResultTransformer 43show_sql 150skalare Werte 105some 113SortedMap 190SortedSet 190Spring

DataSourceTransactionManager 292

Exception Handling 291HibernateCallBack 290Konfiguration 285Problembereich Transaktionssteuerung

287Propagation.MANDATORY 292Propagation.NESTED 292Propagation.NEVER 292Propagation.NOT_SUPPORTED 292Propagation.REQUIRES_NEW 292Propagation.SUPPORTS 292Spring Templates 288Transaktionssteuerung 291

Springframework@Transactional 291AnnotationSessionFactoryBean 286HibernateTransactionManager 291LocalSessionFactoryBean 287Propagation.REQUIRED 291

SQL 104SQLServerDialect 23StaleObjectStateException 100StandardQueryCache 162–163Stored Procedures 125Struts Framework

Exception Handling 294optimistisches Sperren 293Struts 293

subselect 176Swarm Cache 165SybaseDialect 23

T

Tabellen erstellen 29Table 168, 173targetElement = Country.class 340targetEntity = Invoice1.class, 331TemporalType.DATE 329TemporalType.NONE 329TemporalType.TIME 329TemporalType.TIMESTAMP 329ternary 233thread 90Thread local 90ThreadLocalSessionContext 90Tomcat JNDI 154Tools

Eclipse 34

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

Page 49: Galileocomputing Hibernate

370

Index

Hibernate Tools 37IntelliJ 37MyEclipse 34Netbeans 37WebTool-Plugin 58

transaction.auto_close_session 91, 93, 147

transaction.factory_class 147transaction.flush_before_completion 93,

147transaction.manager_lookup_class 147TransactionAttributeType 308

MANDATORY 309NEVER 309NOT_SUPPORTED 309REQUIRED 309REQUIRES_NEW 309SUPPORTS 309

Transaktionssteuerung 76, 80transient 44Treecache 166TreeMap 190TreeSet 190type 26

U

Unidirektional 204uniqueConstraints = { ...} 322uniqueResult 112UnsupportedOperationException 115update=false 206UpdateTimestampsCache 162use_identifer_rollback 151use_sql_comments 116, 151

V

ValidateEventListener 133Validator 133Vererbung 38, 257Versionsspalte 100

W

where 175

X

XML Mappingabstract 176auto-import 172batch-size 175catalog 172, 174check 176class 173default-access 172default-cascade 172default-lazy 172discriminator-value 173dynamic-insert 174dynamic-update 174entity-name 176hibernate-mapping 172lazy 175mutable 173name 173node 176optimistic-lock 175package 173persister 175polymorphism 175proxy 174rowid 176schema 172–173select-before-update 174subselect 176table 173where 175XML Mapping 167

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