4. Java Persistence API (JPA) -...

105
Prof. Dr. Stephan Kleuker 141 Komponentenbasierte Software- Entwicklung 4. Java Persistence API (JPA) Problem: OO in relationale DB Idee des Persistence Mapper Einfache Entity-Klasse Lebenslauf eines Entity-Objekts Umsetzung von 1:N- und M:N-Relationen Geordnete Daten • Anfragen • Vererbung • Validierung

Transcript of 4. Java Persistence API (JPA) -...

Page 1: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

141Komponentenbasierte Software-Entwicklung

4. Java Persistence API (JPA)

• Problem: OO in relationale DB

• Idee des Persistence Mapper

• Einfache Entity-Klasse

• Lebenslauf eines Entity-Objekts

• Umsetzung von 1:N- und M:N-Relationen

• Geordnete Daten

• Anfragen

• Vererbung

• Validierung

Page 2: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

142Komponentenbasierte Software-Entwicklung

Literatur

• JPA 2.0: Sun Microsystem: JSR 317: JavaTM Persistence 2.0 http://jcp.org/en/jsr/summary?id=317 (persistence-2_0_final-spec.pdf ist der Standard; trotzdem sehr gut lesbar!)

Auch für Teile der weiteren Vorlesung

• C. Bauer, G. King, Java Persistence with Hibernate, Manning, Greenwich (USA) 2007

• M. Keith, M. Schincariol, Pro EJB 3 - Java Persistence API, Apress, Berkeley (USA), 2006

Page 3: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

143Komponentenbasierte Software-Entwicklung

Klassische Wege zur Verbindung SW und DB

DB werden meist nicht alleine entwickelt, sie müssen mit umgebender SW integriert werden. Es gibt verschiedene Ansätze, die gerade bei der Anbindung von OO-SW relevant sind:

- SW wird (z.B: mit PL/SQL) in der Datenbank entwickelt (hierzu gibt es auch objektorientierte Ansätze), externe SW kann auf Prozeduren und Funktionen zugreifen.

- SQL-Aufrufe werden direkt in die SW eingebettet (Embedded SQL) bzw. Aufrufe werden durch ein einfaches Framework (z.B. JDBC, SQLJ) gekapselt. (Frage: wie bekomme ich Objekte in die DB?)

- DB-Entwicklung und SW-Entwicklung wird eng miteinander verzahnt, hierzu stehen ausgereifte Development-Frameworks zur Verfügung (EJB, .NET)

Page 4: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

144Komponentenbasierte Software-Entwicklung

Nutzung relationaler DB in OO-Programmen

• Bisheriger Ansatz: relationale DB vorhanden, wird an OO-Programm angeschlossen.

• Was ist, wenn DB zusammen mit OO-Programm entwickelt wird?

• erster Ansatz: warum nicht genau so vorgehen

relationale Datenbank

DB-Zugriffsschicht

Oberfläche + Geschäftslogik

z.B. JDBC

Page 5: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

145Komponentenbasierte Software-Entwicklung

Lagerverwaltung (ein kleines OO-Modell)

Lebensmittel-verfallsdatum : Date

+verlustAm(stichtag : Date) : float

Buch

+verkaufspreis() : float

Lagerraum-nummer : String

+verkaufswertBerechnen() : float

Produkt-name : String-lagermenge : int-preis : float

+Produkt() : Produkt+verfuegbareAnzahl() : int+verkauft(anzahl : int) : void+einlagern(anzahl : int) : void+verkaufspreis() : float

1

beinhaltet-artikel

*1

- artikel bezeichnet eine Collection von Produkten in einem Lagerraum- mit verkaufspreis() wird die Mehrwertsteuer eingerechnet, die bei Büchern anders sein soll.

Page 6: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

146Komponentenbasierte Software-Entwicklung

Aufgabe und Ansatz

• Objekte der im Lagerhaltungsmodell vorgestellten Klassen sollen persistent in einer relationalen DB abgespeichert werden

• Bei der Anbindung an die Datenbank sollen möglichst viele OO-Errungenschaften (Kapselung, Vererbung, Polymorphismus) übernommen werden

• Grundidee: Das Klassendiagramm kann ohne Methoden als ER-Diagramm gelesen werden, es beinhaltet eine 1:N und zwei 1:C Beziehungen.

• Anmerkung: Dieser Übersetzungsansatz war ein beliebtes Tummelfeld von Programmierern ☺, es wird nur ein möglicher Ansatz vorgestellt.

Page 7: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

147Komponentenbasierte Software-Entwicklung

Umgang mit Kapselung

• Objekte der Klasse Produkt können leicht

in folgende Tabelle übersetzt werden.

• zusätzlicher Primary Key vergeben, falls name nicht eindeutig

• Kapselungsidee wird aufgegeben, da man über die Datenbank immer direkt auf die Attribute zugreifen kann, nur durch Mehraufwand einschränkbar:

– Lösung auf der Zugriffsebene im OO-Programm (umgehbar)

– Spezielle Nutzer und Rechte, Nutzung von Views (Aufwand)

OID name lagermenge preis

Produkt

Produkt-name : String-lagermenge : int-preis : float

+Produkt() : Produkt+verfuegbareAnzahl() : int+verkauft(anzahl : int) : void+einlagern(anzahl : int) : void+verkaufspreis() : float

Page 8: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

148Komponentenbasierte Software-Entwicklung

Anmerkungen

• Typischerweise werden Klassenvariablen nicht mit den jeweiligen Objekten abgespeichert, sie müssen explizit behandelt werden

• Es stellt sich generell die Frage, welche zusätzlichen Informationen in welchen Tabellen verwaltet werden sollen

Page 9: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

149Komponentenbasierte Software-Entwicklung

Umgang mit Vererbung

• Vererbung kann durch eine zusätzliche Tabelle mit einer Referenz implementiert werden, dabei ist OID Schlüssel und Fremdschlüssel aus Produkt

Lebensmittel-verfallsdatum : Date

+verlustAm(stichtag : Date) : float

Produkt

OID verfallsdatum

• Für jede Vererbungsebene wird eine neue Tabelle benötigt, was den Zugriff aufwändig macht

• Durch die vorgeschlagene Struktur wird die Sichtweise „ein Lebensmittel ist ein Produkt“ unterstützt

Lebensmittel

Page 10: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

150Komponentenbasierte Software-Entwicklung

• Wie funktioniert Polymorphismus?public float verkaufswertBerechnen(){public float verkaufswertBerechnen(){public float verkaufswertBerechnen(){public float verkaufswertBerechnen(){float ergebnis=0.0f;float ergebnis=0.0f;float ergebnis=0.0f;float ergebnis=0.0f;for(Produkt tmp:artikel)for(Produkt tmp:artikel)for(Produkt tmp:artikel)for(Produkt tmp:artikel)ergebnis= ergebnis+ ergebnis= ergebnis+ ergebnis= ergebnis+ ergebnis= ergebnis+

tmp.verfuegbareAnzahl()*tmp.verkaufspreis();tmp.verfuegbareAnzahl()*tmp.verkaufspreis();tmp.verfuegbareAnzahl()*tmp.verkaufspreis();tmp.verfuegbareAnzahl()*tmp.verkaufspreis();return ergebnis;return ergebnis;return ergebnis;return ergebnis;

}}}}

• In der bisherigen relationalen Übersetzung muss sichergestellt werden, dass das richtige Objekt geladen wird

• Die genaue Klassendefinition bekommt man im vorgestellten Ansatz nur, wenn man alle zu Unterklassen gehörigen Tabellen untersucht, ob die OID vorkommt

• Alternativ kann man sich die genaue Klassenzugehörigkeit in einem weiteren Attribut der Tabelle Produkt merken

Umgang mit Polymorphismus

Page 11: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

151Komponentenbasierte Software-Entwicklung

Umgang mit Objektidentität

• Objektidentität in der Datenbank wird durch den Primary Key garantiert

• Wird das Objekt aus der Datenbank gelesen, ist der Nutzer verantwortlich, dass kein zweites Exemplar des gleichen Objekts geladen wird

– Alternative: Beim ersten Herauslesen wird ein Flag (ein zusätzliches Attribut) gesetzt, dass sich das Exemplar außerhalb der DB befindet (Ansatz fordert viel Programmierdisziplin, insbesondere bei der Programmterminierung)

Page 12: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

152Komponentenbasierte Software-Entwicklung

Umgang mit Beziehungen zwischen Objekten

• Exemplarvariablen, die Collections oder andere nicht triviale Objekttypen enthalten, müssen explizit durch eine oder mehrere Relationen oder Erweiterungen von Tabellen modelliert werden (der Ansatz ist vom Übergang vom ER-Diagramm zur Tabellenstruktur bekannt)

• Frage: Warum passt die skizzierte Lösung eigentlich nicht zum UML-Diagramm?

Lagerraum Produkt1

beinhaltet-artikel

*1

OID name lagermenge preis lagerraum_OID

Produkt

Page 13: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

153Komponentenbasierte Software-Entwicklung

Bearbeiten von Objekten

• Wir haben gesehen, dass einfache Objekte häufig über mehrere Tabellen verteilt werden, d.h. zum Einlesen und Bearbeiten sind relativ aufwändige SQL-JOINS notwendig

• Weiterhin muss das OO-Programm die eindeutige Referenz eines Objektes in der relationalen DB kennen

• Beispiel: Einlesen eines Lebensmittels, das an eine Variable mit Namen „banane“ gebunden war

SELECT name, lagermenge, preis, verfallsdatumSELECT name, lagermenge, preis, verfallsdatumSELECT name, lagermenge, preis, verfallsdatumSELECT name, lagermenge, preis, verfallsdatum

FROM Identifikation, Lebensmittel, ProduktFROM Identifikation, Lebensmittel, ProduktFROM Identifikation, Lebensmittel, ProduktFROM Identifikation, Lebensmittel, Produkt

WHERE Identifikation.Name = 'banane'WHERE Identifikation.Name = 'banane'WHERE Identifikation.Name = 'banane'WHERE Identifikation.Name = 'banane'

AND Identifikation.OID = Produkt.OIDAND Identifikation.OID = Produkt.OIDAND Identifikation.OID = Produkt.OIDAND Identifikation.OID = Produkt.OID

AND Produkt.OID = Lebensmittel.OID AND Produkt.OID = Lebensmittel.OID AND Produkt.OID = Lebensmittel.OID AND Produkt.OID = Lebensmittel.OID

Page 14: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

154Komponentenbasierte Software-Entwicklung

Zwischenfazit

• Selbst bei Beispielen, in denen der Einsatz relationaler Datenbanken sinnvoller Standard ist (Lagerverwaltung), wird die Verknüpfung eines OO-Programms mit relationaler Datenhaltung aufwändig

• Die Nutzung relationaler Datenbanken in OO-Programmen sollte immer über eine DB-Kapselung, die den Zugriff auf die DB regelt, erfolgen

• Für den Kapselungsansatz stehen verschiedene Produkte zur Verfügung (z. B. Hibernate, EclipseLink(TopLink)) , JPA spezifiziert gemeinsames Interface

• Verwandte Ansätze: direkte Nutzung einer OO-Datenbank, Programmierung mit JDO

Page 15: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

155Komponentenbasierte Software-Entwicklung

Konzept von Persistence-Mappern

• Persistence-Mapper (PM) muss wissen, welche Objekte persistiert werden sollen -> markiere Klassen, deren Objekte verwaltet werden sollen

• Persistence-Mapper muss Beziehungen zwischen Objekten kennen

• Ablauf: Nutzer benutzt Objekt unter Verwaltung; dann übernimmt PM die Überwachung, führt Änderungen aus, regelt den Zugriff mehrerer Nutzer

• Ablauf: Nutzer erzeugt Objekt und muss PM einmal mitteilen, dieses zu verwalten

• PM kann selbst regeln, wie Aufgaben realisiert werden (Tabellenstruktur, Transaktionssteuerung)

Page 16: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

156Komponentenbasierte Software-Entwicklung

package jpa20beispiel1;package jpa20beispiel1;package jpa20beispiel1;package jpa20beispiel1;import javax.persistence.Entity;import javax.persistence.Entity;import javax.persistence.Entity;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.Id;import javax.persistence.Id;import javax.persistence.Id;@Entity@Entity@Entity@Entitypublic class Mitarbeiter {public class Mitarbeiter {public class Mitarbeiter {public class Mitarbeiter {@Id private int minr;@Id private int minr;@Id private int minr;@Id private int minr;private String name;private String name;private String name;private String name;

public Mitarbeiter(){} //parameterloser Konstruktor benötigtpublic Mitarbeiter(){} //parameterloser Konstruktor benötigtpublic Mitarbeiter(){} //parameterloser Konstruktor benötigtpublic Mitarbeiter(){} //parameterloser Konstruktor benötigt

public Mitarbeiter(int minr, String name) { //erlaubtpublic Mitarbeiter(int minr, String name) { //erlaubtpublic Mitarbeiter(int minr, String name) { //erlaubtpublic Mitarbeiter(int minr, String name) { //erlaubtthis.minr = minr;this.minr = minr;this.minr = minr;this.minr = minr;this.name = name;this.name = name;this.name = name;this.name = name;

}}}}

public int getMinr() {return minr;}public int getMinr() {return minr;}public int getMinr() {return minr;}public int getMinr() {return minr;}public void setMinr(int minr) {this.minr = minr;}public void setMinr(int minr) {this.minr = minr;}public void setMinr(int minr) {this.minr = minr;}public void setMinr(int minr) {this.minr = minr;}public String getName() {return name;}public String getName() {return name;}public String getName() {return name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public void setName(String name) {this.name = name;}public void setName(String name) {this.name = name;}public void setName(String name) {this.name = name;}

}}}}

Beispiel (1/7)

Page 17: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

157Komponentenbasierte Software-Entwicklung

Beispiel (2/7)• persistence.xml liegt im Ordner META-INF (projektartabhängig)

• Detaileinstellungen von JPA-Realisierung abhängig (z. B. EclispeLink (basiert auf TopLink), Hibernate, Apache OpenJPA)

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

xmlns="http://java.sun.com/xml/ns/persistence" xmlns="http://java.sun.com/xml/ns/persistence" xmlns="http://java.sun.com/xml/ns/persistence" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchema----instance" instance" instance" instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

<persistence<persistence<persistence<persistence----unit name="JPA20Beispiel1PU" unit name="JPA20Beispiel1PU" unit name="JPA20Beispiel1PU" unit name="JPA20Beispiel1PU" transactiontransactiontransactiontransaction----type="RESOURCE_LOCAL"> type="RESOURCE_LOCAL"> type="RESOURCE_LOCAL"> type="RESOURCE_LOCAL">

<provider><provider><provider><provider>org.eclipse.persistence.jpa.PersistenceProviderorg.eclipse.persistence.jpa.PersistenceProviderorg.eclipse.persistence.jpa.PersistenceProviderorg.eclipse.persistence.jpa.PersistenceProvider

</provider></provider></provider></provider><class>jpa20beispiel1.Mitarbeiter</class><class>jpa20beispiel1.Mitarbeiter</class><class>jpa20beispiel1.Mitarbeiter</class><class>jpa20beispiel1.Mitarbeiter</class>

Page 18: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

158Komponentenbasierte Software-Entwicklung

Beispiel (3/7)<<<<propertiespropertiespropertiesproperties>>>><<<<propertypropertypropertyproperty namenamenamename="javax.persistence.jdbc.url" ="javax.persistence.jdbc.url" ="javax.persistence.jdbc.url" ="javax.persistence.jdbc.url"

valuevaluevaluevalue="="="="jdbc:derbyjdbc:derbyjdbc:derbyjdbc:derby://://://://localhost:1527/Spielerei"/>localhost:1527/Spielerei"/>localhost:1527/Spielerei"/>localhost:1527/Spielerei"/><<<<propertypropertypropertyproperty namenamenamename="="="="javax.persistence.jdbc.passwordjavax.persistence.jdbc.passwordjavax.persistence.jdbc.passwordjavax.persistence.jdbc.password" " " "

valuevaluevaluevalue="="="="kleukerkleukerkleukerkleuker"/>"/>"/>"/><<<<propertypropertypropertyproperty namenamenamename="="="="javax.persistence.jdbc.driverjavax.persistence.jdbc.driverjavax.persistence.jdbc.driverjavax.persistence.jdbc.driver" " " "

valuevaluevaluevalue="="="="org.apache.derby.jdbc.ClientDriverorg.apache.derby.jdbc.ClientDriverorg.apache.derby.jdbc.ClientDriverorg.apache.derby.jdbc.ClientDriver"/>"/>"/>"/><<<<propertypropertypropertyproperty namenamenamename="="="="javax.persistence.jdbc.userjavax.persistence.jdbc.userjavax.persistence.jdbc.userjavax.persistence.jdbc.user" " " "

valuevaluevaluevalue="="="="kleukerkleukerkleukerkleuker"/>"/>"/>"/><<<<propertypropertypropertyproperty namenamenamename="="="="eclipselink.ddleclipselink.ddleclipselink.ddleclipselink.ddl----generation" generation" generation" generation"

valuevaluevaluevalue="="="="dropdropdropdrop----andandandand----createcreatecreatecreate----tablestablestablestables"/>"/>"/>"/></</</</propertiespropertiespropertiesproperties>>>>

</</</</persistencepersistencepersistencepersistence----unit>unit>unit>unit></</</</persistencepersistencepersistencepersistence>>>>

Page 19: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

159Komponentenbasierte Software-Entwicklung

Beispiel (4/7)

Page 20: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

160Komponentenbasierte Software-Entwicklung

Beispiel (5/7)

packagepackagepackagepackage jpa20beispiel1;jpa20beispiel1;jpa20beispiel1;jpa20beispiel1;importimportimportimport java.util.Listjava.util.Listjava.util.Listjava.util.List;;;;importimportimportimport javax.persistence.EntityManagerjavax.persistence.EntityManagerjavax.persistence.EntityManagerjavax.persistence.EntityManager;;;;importimportimportimport javax.persistence.EntityManagerFactoryjavax.persistence.EntityManagerFactoryjavax.persistence.EntityManagerFactoryjavax.persistence.EntityManagerFactory;;;;importimportimportimport javax.persistence.Persistencejavax.persistence.Persistencejavax.persistence.Persistencejavax.persistence.Persistence;;;;

publicpublicpublicpublic classclassclassclass Main {Main {Main {Main {

private private private private EntityManagerFactoryEntityManagerFactoryEntityManagerFactoryEntityManagerFactory emfemfemfemf = Persistence.= Persistence.= Persistence.= Persistence.createEntityManagerFactorycreateEntityManagerFactorycreateEntityManagerFactorycreateEntityManagerFactory("JPA20Beispiel1PU");("JPA20Beispiel1PU");("JPA20Beispiel1PU");("JPA20Beispiel1PU");

private private private private EntityManagerEntityManagerEntityManagerEntityManager emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager();();();();

publicpublicpublicpublic void void void void beispieldatenbeispieldatenbeispieldatenbeispieldaten() {() {() {() {String String String String namennamennamennamen[] = {"Egon", "Erwin", "Ute", [] = {"Egon", "Erwin", "Ute", [] = {"Egon", "Erwin", "Ute", [] = {"Egon", "Erwin", "Ute", """"AiseAiseAiseAise"};"};"};"};em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();forforforfor ((((intintintint i=0; i<i=0; i<i=0; i<i=0; i<namen.lengthnamen.lengthnamen.lengthnamen.length; i++); i++); i++); i++)em.persistem.persistem.persistem.persist((((newnewnewnew Mitarbeiter(Mitarbeiter(Mitarbeiter(Mitarbeiter(i,nameni,nameni,nameni,namen[i]));[i]));[i]));[i]));

em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();}}}}

Page 21: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

161Komponentenbasierte Software-Entwicklung

Beispiel (6/7)

publicpublicpublicpublic void void void void datenZeigendatenZeigendatenZeigendatenZeigen() {() {() {() {forforforfor (Mitarbeiter m : (Mitarbeiter m : (Mitarbeiter m : (Mitarbeiter m : em.createQueryem.createQueryem.createQueryem.createQuery((((

"SELECT m FROM Mitarbeiter m","SELECT m FROM Mitarbeiter m","SELECT m FROM Mitarbeiter m","SELECT m FROM Mitarbeiter m",Mitarbeiter.classMitarbeiter.classMitarbeiter.classMitarbeiter.class) ) ) ) ....getResultListgetResultListgetResultListgetResultList()) {()) {()) {()) {

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((m.getMinrm.getMinrm.getMinrm.getMinr() + ": " + () + ": " + () + ": " + () + ": " + m.getNamem.getNamem.getNamem.getName());());());());}}}}

}}}}

publicpublicpublicpublic void void void void schliessenschliessenschliessenschliessen() {() {() {() {ifififif ((((emememem != null && != null && != null && != null && em.isOpenem.isOpenem.isOpenem.isOpen()) {()) {()) {()) {em.closeem.closeem.closeem.close();}();}();}();}ifififif ((((emfemfemfemf != null && != null && != null && != null && emf.isOpenemf.isOpenemf.isOpenemf.isOpen()) {()) {()) {()) {emf.closeemf.closeemf.closeemf.close();}();}();}();}

} } } }

publicpublicpublicpublic staticstaticstaticstatic void void void void mainmainmainmain(String[] (String[] (String[] (String[] argsargsargsargs) {) {) {) {Main m = Main m = Main m = Main m = newnewnewnew Main();Main();Main();Main();m.beispieldatenm.beispieldatenm.beispieldatenm.beispieldaten();();();();m.datenZeigenm.datenZeigenm.datenZeigenm.datenZeigen();();();();m.schliessenm.schliessenm.schliessenm.schliessen();();();();

}}}}}}}}

1: Egon1: Egon1: Egon1: Egon

2: Erwin2: Erwin2: Erwin2: Erwin

4: 4: 4: 4: AiseAiseAiseAise

3: Ute3: Ute3: Ute3: Ute

Page 22: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

162Komponentenbasierte Software-Entwicklung

Beispiel (7/7)

• Falls noch keine Tabelle Mitarbeiter existiert, wird diese angelegt

Page 23: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

163Komponentenbasierte Software-Entwicklung

Suchen und Bearbeiten von einzelnen Objekten

public void namenAendern(){public void namenAendern(){public void namenAendern(){public void namenAendern(){int eingabe=int eingabe=int eingabe=int eingabe=----1;1;1;1;while(eingabe!=0){while(eingabe!=0){while(eingabe!=0){while(eingabe!=0){System.out.print("Welche Nummer (Ende mit 0): ");System.out.print("Welche Nummer (Ende mit 0): ");System.out.print("Welche Nummer (Ende mit 0): ");System.out.print("Welche Nummer (Ende mit 0): ");eingabe=new Scanner(System.in).nextInt();eingabe=new Scanner(System.in).nextInt();eingabe=new Scanner(System.in).nextInt();eingabe=new Scanner(System.in).nextInt();Mitarbeiter m = em.find(Mitarbeiter.class, eingabe);Mitarbeiter m = em.find(Mitarbeiter.class, eingabe);Mitarbeiter m = em.find(Mitarbeiter.class, eingabe);Mitarbeiter m = em.find(Mitarbeiter.class, eingabe);if(m == null)if(m == null)if(m == null)if(m == null)System.out.println("Witzbold");System.out.println("Witzbold");System.out.println("Witzbold");System.out.println("Witzbold");

else{else{else{else{System.out.print("Neuer Name (alt:"+m.getName()+"): ");System.out.print("Neuer Name (alt:"+m.getName()+"): ");System.out.print("Neuer Name (alt:"+m.getName()+"): ");System.out.print("Neuer Name (alt:"+m.getName()+"): ");String name=new Scanner(System.in).next(); String name=new Scanner(System.in).next(); String name=new Scanner(System.in).next(); String name=new Scanner(System.in).next(); EntityTransaction tr = em.getTransaction();EntityTransaction tr = em.getTransaction();EntityTransaction tr = em.getTransaction();EntityTransaction tr = em.getTransaction();tr.begin();tr.begin();tr.begin();tr.begin();m.setName(name);m.setName(name);m.setName(name);m.setName(name);tr.commit();tr.commit();tr.commit();tr.commit();

}}}}}}}}

}}}}

Page 24: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

164Komponentenbasierte Software-Entwicklung

Zentrale Klassen

• Aufbau der VerbindungEntityManagerFactory emf = Persistence. EntityManagerFactory emf = Persistence. EntityManagerFactory emf = Persistence. EntityManagerFactory emf = Persistence.

createEntityManagerFactory("JPA20Beispiel1PU");createEntityManagerFactory("JPA20Beispiel1PU");createEntityManagerFactory("JPA20Beispiel1PU");createEntityManagerFactory("JPA20Beispiel1PU");

– Einrichtung sehr aufwändig, selten neu erstellen

• Einrichtung der Verbindung für den NutzerEntityManager em = emf.createEntityManager();EntityManager em = emf.createEntityManager();EntityManager em = emf.createEntityManager();EntityManager em = emf.createEntityManager();

– kostet Zeit, gibt trotzdem meist sinnvoll Objekt häufiger zu erzeugen und zu schließen/löschen

• Nutzung einer TransaktionEntityTransaction tr = em.getTransaction();EntityTransaction tr = em.getTransaction();EntityTransaction tr = em.getTransaction();EntityTransaction tr = em.getTransaction();

– kurzfristig nutzen: Daten vorbereiten, dann DB-Zugriff, dann schließen

• letztendlich immer alles schließen (typisch in finally-Block)

• Generelles Verhalten hängt von DB ab, in Großprojekten immer mit erfahrenem DB-Administrator arbeiten

Page 25: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

165Komponentenbasierte Software-Entwicklung

Entity ist POJO

Entity-Klassen-Objekte sind klassische Plain Old Java Objects

• Verpflichtung:

– public (oder protected) Konstruktor ohne Parameter

– Exemplarvariablen private oder protected, Zugriff über get... und set...

– Klasse, Methoden, Exemplarvariablen nicht final

– Serialisierbar [zumindest sehr sinnvoll]

• keine weiteren Einschränkungen

– beliebige weitere Methoden

– Vererbung (auch Entity von Nicht-Entity [aufwändig])

– Nutzung abstrakte Klassen

Page 26: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

166Komponentenbasierte Software-Entwicklung

Primary Key

Typisch: Primary Key wird erzeugt

@Id@Id@Id@Id

@GeneratedValue(strategy = GenerationType.AUTO)@GeneratedValue(strategy = GenerationType.AUTO)@GeneratedValue(strategy = GenerationType.AUTO)@GeneratedValue(strategy = GenerationType.AUTO)

private int minr;private int minr;private int minr;private int minr;

folgende Datentypen erlaubt

• primitive Java-Typen (int, long, …)

• Wrapper von primitiven Java-Typen (Integer, Long, …)

• java.lang.String

• java.util.Date

• java.sql.Date

Page 27: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

167Komponentenbasierte Software-Entwicklung

Persistierbare Typen/Klassen

• Primitive Typen (byte, char, int, long, float, double, boolean)

• java.lang.String

• Andere serialisierbare Typen:

– Wrapper der primitiven Typen

– java.math.BigInteger

– java.math.BigDecimal

– java.util.Date, java.util.Calendar

– java.sql.Date, java.sql.Time, java.sql.TimeStamp

– Nutzerdefinierte serialisierbare Typen

– byte[], Byte[], char[], Character[]

• Enumeration

• Andere Entities

• Collections von Entities (Collection, Set, List, Map)

Page 28: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

168Komponentenbasierte Software-Entwicklung

Persistent Fields / Properties

• Persistent Fields

– @Id private int minr;@Id private int minr;@Id private int minr;@Id private int minr;

– Exemplarvariablen direkt annotiert

– Zugriff des Persistence-Frameworks direkt auf Variablen

– Vorteil: Variable und Annotation stehen direkt zusammen

• Persistent Properties

– @Id public int getMinr{ return this.minr; }@Id public int getMinr{ return this.minr; }@Id public int getMinr{ return this.minr; }@Id public int getMinr{ return this.minr; }

– get-Methode wird annotiert

– Zugriff auf Exemplarvariablen muss immer über Standard get erfolgen (auch in der Klasse selbst)

– Vorteil: Flexibilität, da Methode weitere Funktionalität haben kann

Page 29: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

169Komponentenbasierte Software-Entwicklung

Annotationen zur Flexibilisierung / Ergänzung

@Entity@Entity@Entity@Entity

@Table(@Table(@Table(@Table(namenamenamename="Chef")="Chef")="Chef")="Chef")

publicpublicpublicpublic classclassclassclass Mitarbeiter Mitarbeiter Mitarbeiter Mitarbeiter implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;

@@@@IdIdIdId

@@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValue((((strategystrategystrategystrategy = = = = GenerationType.AUTOGenerationType.AUTOGenerationType.AUTOGenerationType.AUTO))))

private private private private intintintint minrminrminrminr;;;;

@@@@ColumnColumnColumnColumn((((namenamenamename="Leiter", ="Leiter", ="Leiter", ="Leiter", nullablenullablenullablenullable=false,=false,=false,=false,

updatableupdatableupdatableupdatable=true, =true, =true, =true, uniqueuniqueuniqueunique=true)=true)=true)=true)

private String private String private String private String namenamenamename;;;;

............

Page 30: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

170Komponentenbasierte Software-Entwicklung

PersistenceContext

• Wird für Objekte vorher festgehaltener Klassen definiert

• Entspricht einem Cache, der MANAGED-Objekte verwaltet

• EntityManager-Objekt für konkreten PersistenceContext

• EntityManager-Operationen arbeiten auf dem Cache

• Man muss EntityManager mitteilen, dass Daten in die DB geschrieben werden müssenem.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();

• Beim Schreiben können wg. der Transaktionssteuerung der DB Exceptions auftreten (abhängig von Steuerungsart)

• Im Zweifel bei Entwicklung immer echte Tabellen anschauen

• Üblich: nur kurz lebende EntityManager (erzeugen, Aktion, schließen)

Page 31: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

171Komponentenbasierte Software-Entwicklung

Beispiel für Cache (1/2)

@Entity@Entity@Entity@Entitypublic class Mitarbeiter implements Serializable {public class Mitarbeiter implements Serializable {public class Mitarbeiter implements Serializable {public class Mitarbeiter implements Serializable {

@Id @GeneratedValue@Id @GeneratedValue@Id @GeneratedValue@Id @GeneratedValueprivate int minr;private int minr;private int minr;private int minr;

@Column(length=2) //maximal zwei Zeichen@Column(length=2) //maximal zwei Zeichen@Column(length=2) //maximal zwei Zeichen@Column(length=2) //maximal zwei Zeichenprivate String name;private String name;private String name;private String name;

public Mitarbeiter() {public Mitarbeiter() {public Mitarbeiter() {public Mitarbeiter() {} //parameterloser Konstruktor benötigt} //parameterloser Konstruktor benötigt} //parameterloser Konstruktor benötigt} //parameterloser Konstruktor benötigt

public Mitarbeiter(String name) {public Mitarbeiter(String name) {public Mitarbeiter(String name) {public Mitarbeiter(String name) {this.name = name;this.name = name;this.name = name;this.name = name;

} } } } // get// get// get// get---- und setund setund setund set----Methoden weggelassenMethoden weggelassenMethoden weggelassenMethoden weggelassen

@Override public String toString(){@Override public String toString(){@Override public String toString(){@Override public String toString(){return name+"("+minr+")";return name+"("+minr+")";return name+"("+minr+")";return name+"("+minr+")";

}}}}}}}}

Page 32: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

172Komponentenbasierte Software-Entwicklung

Beispiel für Cache (2/2)

public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) {EntityManagerFactory emf = EntityManagerFactory emf = EntityManagerFactory emf = EntityManagerFactory emf =

Persistence.createEntityManagerFactory("JPACachePU");Persistence.createEntityManagerFactory("JPACachePU");Persistence.createEntityManagerFactory("JPACachePU");Persistence.createEntityManagerFactory("JPACachePU");EntityManager em=emf.createEntityManager();EntityManager em=emf.createEntityManager();EntityManager em=emf.createEntityManager();EntityManager em=emf.createEntityManager();em.getTransaction().begin();em.getTransaction().begin();em.getTransaction().begin();em.getTransaction().begin();em.persist(new Mitarbeiter("ET"));em.persist(new Mitarbeiter("ET"));em.persist(new Mitarbeiter("ET"));em.persist(new Mitarbeiter("ET"));em.persist(new Mitarbeiter("JFK"));em.persist(new Mitarbeiter("JFK"));em.persist(new Mitarbeiter("JFK"));em.persist(new Mitarbeiter("JFK"));for(int i=1;i<3;i++)for(int i=1;i<3;i++)for(int i=1;i<3;i++)for(int i=1;i<3;i++)System.out.println(em.find(Mitarbeiter.class,i));System.out.println(em.find(Mitarbeiter.class,i));System.out.println(em.find(Mitarbeiter.class,i));System.out.println(em.find(Mitarbeiter.class,i));

em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();em.close();em.close();em.close();em.close();}}}}

}}}}ET(1)ET(1)ET(1)ET(1)JFK(2)JFK(2)JFK(2)JFK(2)[EL Warning]: 2010[EL Warning]: 2010[EL Warning]: 2010[EL Warning]: 2010----03030303----28 13:12:57.86828 13:12:57.86828 13:12:57.86828 13:12:57.868----UnitOfWork(20290587)UnitOfWork(20290587)UnitOfWork(20290587)UnitOfWork(20290587)----Exception [EclipseLinkException [EclipseLinkException [EclipseLinkException [EclipseLink----4002]: 4002]: 4002]: 4002]: org.eclipse.persistence.exceptions.DatabaseExceptionorg.eclipse.persistence.exceptions.DatabaseExceptionorg.eclipse.persistence.exceptions.DatabaseExceptionorg.eclipse.persistence.exceptions.DatabaseExceptionInternal Exception: java.sql.SQLDataException: Bei dem Internal Exception: java.sql.SQLDataException: Bei dem Internal Exception: java.sql.SQLDataException: Bei dem Internal Exception: java.sql.SQLDataException: Bei dem Versuch, VARCHAR 'JFK' auf die Länge 2 zu kürzen, ist Versuch, VARCHAR 'JFK' auf die Länge 2 zu kürzen, ist Versuch, VARCHAR 'JFK' auf die Länge 2 zu kürzen, ist Versuch, VARCHAR 'JFK' auf die Länge 2 zu kürzen, ist ein Abschneidefehler aufgetreten.ein Abschneidefehler aufgetreten.ein Abschneidefehler aufgetreten.ein Abschneidefehler aufgetreten.

Page 33: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

173Komponentenbasierte Software-Entwicklung

Lebenslauf eines Entity-Objekts

NEW -> merge() führt evtl. zur Mehrfachobjekterzeugungrefresh() nur, wenn vorher persistiert

Page 34: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

174Komponentenbasierte Software-Entwicklung

Unterschied: Lokal und DB immer beachten

public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) {EntityManagerFactory emf = Persistence.EntityManagerFactory emf = Persistence.EntityManagerFactory emf = Persistence.EntityManagerFactory emf = Persistence.

createEntityManagerFactory("JPA20Beispiel1PU");createEntityManagerFactory("JPA20Beispiel1PU");createEntityManagerFactory("JPA20Beispiel1PU");createEntityManagerFactory("JPA20Beispiel1PU");EntityManager em = emf.createEntityManager();EntityManager em = emf.createEntityManager();EntityManager em = emf.createEntityManager();EntityManager em = emf.createEntityManager();Mitarbeiter m1 = new Mitarbeiter("Ford");Mitarbeiter m1 = new Mitarbeiter("Ford");Mitarbeiter m1 = new Mitarbeiter("Ford");Mitarbeiter m1 = new Mitarbeiter("Ford");Mitarbeiter m2 = new Mitarbeiter("Arthur");Mitarbeiter m2 = new Mitarbeiter("Arthur");Mitarbeiter m2 = new Mitarbeiter("Arthur");Mitarbeiter m2 = new Mitarbeiter("Arthur");em.getTransaction().begin();em.getTransaction().begin();em.getTransaction().begin();em.getTransaction().begin();em.persist(m1);em.persist(m1);em.persist(m1);em.persist(m1);em.persist(m2);em.persist(m2);em.persist(m2);em.persist(m2);em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();m1.setName("Manta");m1.setName("Manta");m1.setName("Manta");m1.setName("Manta");for (Mitarbeiter m : em.createQuery(for (Mitarbeiter m : em.createQuery(for (Mitarbeiter m : em.createQuery(for (Mitarbeiter m : em.createQuery(

"SELECT m FROM Mitarbeiter m", Mitarbeiter.class)"SELECT m FROM Mitarbeiter m", Mitarbeiter.class)"SELECT m FROM Mitarbeiter m", Mitarbeiter.class)"SELECT m FROM Mitarbeiter m", Mitarbeiter.class).getResultList()).getResultList()).getResultList()).getResultList())

System.out.println(m.getMinr() System.out.println(m.getMinr() System.out.println(m.getMinr() System.out.println(m.getMinr() + ": " + m.getName());+ ": " + m.getName());+ ": " + m.getName());+ ": " + m.getName());

em.close();em.close();em.close();em.close();em.refresh(m1);em.refresh(m1);em.refresh(m1);em.refresh(m1);System.out.println(m1);System.out.println(m1);System.out.println(m1);System.out.println(m1);

}}}}

2: Arthur2: Arthur2: Arthur2: Arthur1: Manta1: Manta1: Manta1: MantaFord(1)Ford(1)Ford(1)Ford(1)

Page 35: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

175Komponentenbasierte Software-Entwicklung

Sauberes Persistieren

• Auslagerung der Persistierung in eine Methode mit sauberer Exception-Behandlung

• Anmerkung: man muss nicht immer em.close() machenpublicpublicpublicpublic void void void void persistpersistpersistpersist(Object (Object (Object (Object objectobjectobjectobject) {) {) {) {

em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();trytrytrytry {{{{em.persistem.persistem.persistem.persist((((objectobjectobjectobject););););em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();

} catch (Exception e) {} catch (Exception e) {} catch (Exception e) {} catch (Exception e) {ifififif ((((em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().isActiveisActiveisActiveisActive())())())())em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().rollbackrollbackrollbackrollback();();();();

throwthrowthrowthrow e;e;e;e;} } } } finallyfinallyfinallyfinally {{{{

em.closeem.closeem.closeem.close();();();();}}}}

Page 36: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

176Komponentenbasierte Software-Entwicklung

Notwendigkeit von merge (1/3)

publicpublicpublicpublic classclassclassclass Main {Main {Main {Main {

private private private private EntityManagerFactoryEntityManagerFactoryEntityManagerFactoryEntityManagerFactory emfemfemfemf ====Persistence.createEntityManagerFactoryPersistence.createEntityManagerFactoryPersistence.createEntityManagerFactoryPersistence.createEntityManagerFactory("("("("JPAMergeJPAMergeJPAMergeJPAMerge");");");");

private private private private EntityManagerEntityManagerEntityManagerEntityManager emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager();();();();

public static void main(String[] public static void main(String[] public static void main(String[] public static void main(String[] argsargsargsargs) {) {) {) {new Main().mach1();new Main().mach1();new Main().mach1();new Main().mach1();

}}}}

publicpublicpublicpublic voidvoidvoidvoid datenZeigendatenZeigendatenZeigendatenZeigen() {() {() {() {forforforfor (Mitarbeiter m : (Mitarbeiter m : (Mitarbeiter m : (Mitarbeiter m : em.createQueryem.createQueryem.createQueryem.createQuery((((

"SELECT m FROM Mitarbeiter m","SELECT m FROM Mitarbeiter m","SELECT m FROM Mitarbeiter m","SELECT m FROM Mitarbeiter m",Mitarbeiter.classMitarbeiter.classMitarbeiter.classMitarbeiter.class))))....getResultListgetResultListgetResultListgetResultList()) ()) ()) ())

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((m.getIdm.getIdm.getIdm.getId() + ": " + () + ": " + () + ": " + () + ": " + m.getNamem.getNamem.getNamem.getName());());());());}}}}

Page 37: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

177Komponentenbasierte Software-Entwicklung

Notwendigkeit von merge (2/3)

publicpublicpublicpublic void mach1() {void mach1() {void mach1() {void mach1() {Mitarbeiter m1 = Mitarbeiter m1 = Mitarbeiter m1 = Mitarbeiter m1 = newnewnewnew Mitarbeiter("Urs");Mitarbeiter("Urs");Mitarbeiter("Urs");Mitarbeiter("Urs");em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();em.persistem.persistem.persistem.persist(m1);(m1);(m1);(m1);em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();datenZeigendatenZeigendatenZeigendatenZeigen();();();();Mitarbeiter m2 = Mitarbeiter m2 = Mitarbeiter m2 = Mitarbeiter m2 = em.findem.findem.findem.find((((Mitarbeiter.classMitarbeiter.classMitarbeiter.classMitarbeiter.class, m1.getId());, m1.getId());, m1.getId());, m1.getId());em.closeem.closeem.closeem.close();();();();mach2(m2);mach2(m2);mach2(m2);mach2(m2);

}}}}

publicpublicpublicpublic void mach2(Mitarbeiter m2) {void mach2(Mitarbeiter m2) {void mach2(Mitarbeiter m2) {void mach2(Mitarbeiter m2) {m2.setName("Ute");m2.setName("Ute");m2.setName("Ute");m2.setName("Ute");emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager();();();();em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();em.persistem.persistem.persistem.persist(m2);(m2);(m2);(m2);em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();datenZeigendatenZeigendatenZeigendatenZeigen();();();();em.closeem.closeem.closeem.close();();();();

}}}}}}}}

1: Urs1: Urs1: Urs1: UrsInternal Exception: Internal Exception: Internal Exception: Internal Exception: java.sql.SQLIntegrityConsjava.sql.SQLIntegrityConsjava.sql.SQLIntegrityConsjava.sql.SQLIntegrityConstraintViolationException:traintViolationException:traintViolationException:traintViolationException:.. zu einem duplizierten .. zu einem duplizierten .. zu einem duplizierten .. zu einem duplizierten Schlüsselwert geführt Schlüsselwert geführt Schlüsselwert geführt Schlüsselwert geführt hätte.hätte.hätte.hätte.

Page 38: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

178Komponentenbasierte Software-Entwicklung

Notwendigkeit von merge (3/3)

publicpublicpublicpublic void mach2(Mitarbeiter m2) {void mach2(Mitarbeiter m2) {void mach2(Mitarbeiter m2) {void mach2(Mitarbeiter m2) {

m2.setName("Ute");m2.setName("Ute");m2.setName("Ute");m2.setName("Ute");

emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager();();();();

em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();

////////em.persistem.persistem.persistem.persist(m2);(m2);(m2);(m2);

em.mergeem.mergeem.mergeem.merge(m2);(m2);(m2);(m2);

em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();

datenZeigendatenZeigendatenZeigendatenZeigen();();();();

}}}}

• Hinweis: Verzichtet man zwischenzeitlich auf das Schließen des EntityManagers, funktioniert persist() genauso gut

• zur Aktualisierung sollte merge() genutzt werden

1: Urs1: Urs1: Urs1: Urs

1: Ute1: Ute1: Ute1: Ute

Page 39: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

179Komponentenbasierte Software-Entwicklung

Klasse oder Tabelle?Bei der Entity-Nutzung offen, ob erst Klassen designt und dann

Tabellen entworfen werden

• Einfach: Tabellen existieren; dann typischerweise zur Tabelle eine Entity-Klassse erstellbar (generierbar)

• Wenn nichts gegeben:

– Entwurf der Entity-Klassen (Daten der Applikation mit ihren Abhängigkeiten)

– Ableitung oder Generierung der Tabellen

• Generierungsansätze:

– Drop and Create: beteiligte Tabellen löschen und neu anlegen (Entwicklung und Test)

– Create: wenn nicht existent, dann anlegen (Realität)

– None: wenn nicht existent, dann Fehler (Realität)

• Hinweis: bei Änderungen neu übersetzen

Page 40: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

180Komponentenbasierte Software-Entwicklung

Generelle JEE-Regel

Convention over Configuration

• bedeutet: wenn nichts angegeben wird, wird ein Default-Wert genutzt

• Default-Werte sind zwar sinnvoll, sollte man aber kennen

• Erinnerung: Java-Inkonsistenz

Page 41: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

181Komponentenbasierte Software-Entwicklung

Einschub: XML-Konfiguration

• Statt Annotationen zu nutzen, können diese Informationen auch in XML beschrieben werden

• Typisch: eine XML-Datei pro Klasse + zusammenführende XML-Datei

• Vorteil: Verhaltensänderungen ohne Codeänderung

• Nachteil: viele kleine penibel zu pflegende Dateien

• Auch möglich: XML und Annotationen; dabei „schlägt“ XML die Annotationen

Page 42: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

182Komponentenbasierte Software-Entwicklung

Kardinalitäten in JPA

• 1:1 zu einem A- Objekt gehört (maximal) ein anderes B-Objekt, die jeweils zu (maximal) einem A-Objekt gehören

• 1:N zu einem A-Objekt gehören beliebig viele B-Objekte, die jeweils zu (maximal) einem A-Objekt gehören (N:1 analog)

• M:N zu einem A-Objekt gehören beliebig viele B-Objekte, die jeweils zu beliebig vielen A-Objekten gehören

• Anders als bei Tabellen haben OO-Assoziationen Leserichtungen

• Unidirektional: nur von einer Seite auf die andere schließbar

• Bidirektional: Abhängigkeit in beide Richtungen manövrierbar (es gibt Besitzer der Beziehung; für Updates wichtig)

A Bx y

Page 43: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

183Komponentenbasierte Software-Entwicklung

Umsetzung unidirektional 1:N (1/4)

@Entity@Entity@Entity@Entitypublic class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {

@Id @GeneratedValue private int paid;@Id @GeneratedValue private int paid;@Id @GeneratedValue private int paid;@Id @GeneratedValue private int paid;private String titel;private String titel;private String titel;private String titel;public String getTitel() {public String getTitel() {public String getTitel() {public String getTitel() {return titel;return titel;return titel;return titel;

}}}}

public void setTitel(String titel) {public void setTitel(String titel) {public void setTitel(String titel) {public void setTitel(String titel) {this.titel = titel;this.titel = titel;this.titel = titel;this.titel = titel;

}}}}}}}}

Page 44: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

184Komponentenbasierte Software-Entwicklung

Umsetzung unidirektional 1:N (2/4)

@@@@EntityEntityEntityEntity

publicpublicpublicpublic classclassclassclass Projekt Projekt Projekt Projekt implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

@@@@IdIdIdId @@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValue

private private private private intintintint projektidprojektidprojektidprojektid;;;;

private String private String private String private String namenamenamename;;;;

@@@@OneToManyOneToManyOneToManyOneToMany((((cascadecascadecascadecascade====CascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSIST))))

private Set<Projektauftrag> private Set<Projektauftrag> private Set<Projektauftrag> private Set<Projektauftrag> auftraegeauftraegeauftraegeauftraege;;;;

publicpublicpublicpublic Projekt(){Projekt(){Projekt(){Projekt(){

auftraegeauftraegeauftraegeauftraege = = = = newnewnewnew HashSetHashSetHashSetHashSet<Projektauftrag>();<Projektauftrag>();<Projektauftrag>();<Projektauftrag>();

}}}}

// fehlen // fehlen // fehlen // fehlen getgetgetget---- und und und und setsetsetset----Methoden (auch Methoden (auch Methoden (auch Methoden (auch addaddaddadd wäre sinnvoll)wäre sinnvoll)wäre sinnvoll)wäre sinnvoll)

Page 45: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

185Komponentenbasierte Software-Entwicklung

Umsetzung unidirektional 1:N (3/4)

public void datenAnlegen(){public void datenAnlegen(){public void datenAnlegen(){public void datenAnlegen(){String p[] ={"Hotel", "Noten", "Belegung"};String p[] ={"Hotel", "Noten", "Belegung"};String p[] ={"Hotel", "Noten", "Belegung"};String p[] ={"Hotel", "Noten", "Belegung"};String a[] ={"Analyse", "Modell", "Design"};String a[] ={"Analyse", "Modell", "Design"};String a[] ={"Analyse", "Modell", "Design"};String a[] ={"Analyse", "Modell", "Design"};em.getTransaction().begin();em.getTransaction().begin();em.getTransaction().begin();em.getTransaction().begin();for (int i=0; i<p.length;i++){for (int i=0; i<p.length;i++){for (int i=0; i<p.length;i++){for (int i=0; i<p.length;i++){Projekt pr= new Projekt();Projekt pr= new Projekt();Projekt pr= new Projekt();Projekt pr= new Projekt();pr.setName(p[i]);pr.setName(p[i]);pr.setName(p[i]);pr.setName(p[i]);for (int j=0; j<a.length;j++){for (int j=0; j<a.length;j++){for (int j=0; j<a.length;j++){for (int j=0; j<a.length;j++){Projektauftrag pa= new Projektauftrag();Projektauftrag pa= new Projektauftrag();Projektauftrag pa= new Projektauftrag();Projektauftrag pa= new Projektauftrag();pa.setTitel(a[j]);pa.setTitel(a[j]);pa.setTitel(a[j]);pa.setTitel(a[j]);Set<Projektauftrag> tmp= pr.getAuftraege();Set<Projektauftrag> tmp= pr.getAuftraege();Set<Projektauftrag> tmp= pr.getAuftraege();Set<Projektauftrag> tmp= pr.getAuftraege();tmp.add(pa);tmp.add(pa);tmp.add(pa);tmp.add(pa);

}}}}em.persist(pr);em.persist(pr);em.persist(pr);em.persist(pr);

}}}}em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();

}}}}

Page 46: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

186Komponentenbasierte Software-Entwicklung

Umsetzung unidirektional 1:N (4/4)SELECT PROJEKT.PROJEKTID, PROJEKT.NAME, PROJEKTAUFTRAG.PAID, SELECT PROJEKT.PROJEKTID, PROJEKT.NAME, PROJEKTAUFTRAG.PAID, SELECT PROJEKT.PROJEKTID, PROJEKT.NAME, PROJEKTAUFTRAG.PAID, SELECT PROJEKT.PROJEKTID, PROJEKT.NAME, PROJEKTAUFTRAG.PAID,

PROJEKTAUFTRAG.TITELPROJEKTAUFTRAG.TITELPROJEKTAUFTRAG.TITELPROJEKTAUFTRAG.TITELFROM PROJEKT, PROJEKT_PROJEKTAUFTRAG, PROJEKTAUFTRAGFROM PROJEKT, PROJEKT_PROJEKTAUFTRAG, PROJEKTAUFTRAGFROM PROJEKT, PROJEKT_PROJEKTAUFTRAG, PROJEKTAUFTRAGFROM PROJEKT, PROJEKT_PROJEKTAUFTRAG, PROJEKTAUFTRAGWHERE PROJEKT.PROJEKTID = WHERE PROJEKT.PROJEKTID = WHERE PROJEKT.PROJEKTID = WHERE PROJEKT.PROJEKTID =

PROJEKT_PROJEKTAUFTRAG.PROJEKT_PROJEKTIDPROJEKT_PROJEKTAUFTRAG.PROJEKT_PROJEKTIDPROJEKT_PROJEKTAUFTRAG.PROJEKT_PROJEKTIDPROJEKT_PROJEKTAUFTRAG.PROJEKT_PROJEKTIDAND PROJEKTAUFTRAG.PAID = AND PROJEKTAUFTRAG.PAID = AND PROJEKTAUFTRAG.PAID = AND PROJEKTAUFTRAG.PAID =

PROJEKT_PROJEKTAUFTRAG.AUFTRAEGE_PAID;PROJEKT_PROJEKTAUFTRAG.AUFTRAEGE_PAID;PROJEKT_PROJEKTAUFTRAG.AUFTRAEGE_PAID;PROJEKT_PROJEKTAUFTRAG.AUFTRAEGE_PAID;

Page 47: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

187Komponentenbasierte Software-Entwicklung

Cascade-Varianten

@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})

• MERGE : merge() implizit für verknüpfte Objekte aufrufen

• PERSIST: persist() implizit für verknüpfte Objekte aufrufen

• REFRESH: refresh() implizit für verknüpfte Objekte aufrufen

• REMOVE: remove() implizit für verknüpfte Objekte aufrufen

• ALL: alle vier genannten Möglichkeiten

• Default-Einstellung: keine der fünf Varianten

• Wichtige Design-Entscheidung, was sinnvoll ist

• REMOVE nur bei @OneToOne und @OneToMany nutzbar

Beispiel, wenn Cascade.PERSIST fehlteSCHWERWIEGEND: Could not synchronize database state with sessionSCHWERWIEGEND: Could not synchronize database state with sessionSCHWERWIEGEND: Could not synchronize database state with sessionSCHWERWIEGEND: Could not synchronize database state with session

org.hibernate.TransientObjectException: object references an unsaved org.hibernate.TransientObjectException: object references an unsaved org.hibernate.TransientObjectException: object references an unsaved org.hibernate.TransientObjectException: object references an unsaved transient instance transient instance transient instance transient instance ---- save the transient instance before flushing: save the transient instance before flushing: save the transient instance before flushing: save the transient instance before flushing: ProjektauftragProjektauftragProjektauftragProjektauftrag

Page 48: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

188Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional 1:N (1/5)

- Bidirektionale Relationen haben Eigentümer (owner side) und Abhängigen (inverse side)

- Eigentümer bei 1:N ist N (hier Projektauftrag)

- Abhängiger bekommt mappedBy-Attribut

- Programmierer für Einträge auf beiden Seiten verantwortlich

Page 49: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

189Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional 1:N (2/5)

@Entity@Entity@Entity@Entity

public class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {

@Id @GeneratedValue @Id @GeneratedValue @Id @GeneratedValue @Id @GeneratedValue

private int paid;private int paid;private int paid;private int paid;

private String titel;private String titel;private String titel;private String titel;

@ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST,

CascadeType.MERGE})CascadeType.MERGE})CascadeType.MERGE})CascadeType.MERGE})

private Mitarbeiter bearbeiter;private Mitarbeiter bearbeiter;private Mitarbeiter bearbeiter;private Mitarbeiter bearbeiter;

//...//...//...//...

Page 50: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

190Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional 1:N (3/5)

@@@@EntityEntityEntityEntity

publicpublicpublicpublic classclassclassclass Mitarbeiter Mitarbeiter Mitarbeiter Mitarbeiter implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;

@@@@IdIdIdId

@@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValue((((strategystrategystrategystrategy = = = = GenerationType.AUTOGenerationType.AUTOGenerationType.AUTOGenerationType.AUTO))))

private private private private intintintint minrminrminrminr;;;;

private String private String private String private String namenamenamename;;;;

@@@@OneToManyOneToManyOneToManyOneToMany((((mappedBymappedBymappedBymappedBy="="="="bearbeiterbearbeiterbearbeiterbearbeiter", ", ", ",

cascadecascadecascadecascade={={={={CascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSIST, , , , CascadeType.MERGECascadeType.MERGECascadeType.MERGECascadeType.MERGE})})})})

private Set<Projektauftrag> private Set<Projektauftrag> private Set<Projektauftrag> private Set<Projektauftrag> auftraegeauftraegeauftraegeauftraege = = = =

newnewnewnew HashSetHashSetHashSetHashSet<Projektauftrag>();<Projektauftrag>();<Projektauftrag>();<Projektauftrag>();

publicpublicpublicpublic voidvoidvoidvoid auftragHinzuauftragHinzuauftragHinzuauftragHinzu(Projektauftrag (Projektauftrag (Projektauftrag (Projektauftrag papapapa){){){){

auftraege.addauftraege.addauftraege.addauftraege.add((((papapapa););););

} // ...} // ...} // ...} // ...

Page 51: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

191Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional 1:N (4/5)publicpublicpublicpublic void void void void mitarbeiterZuordnenmitarbeiterZuordnenmitarbeiterZuordnenmitarbeiterZuordnen(){(){(){(){Mitarbeiter m[]= {Mitarbeiter m[]= {Mitarbeiter m[]= {Mitarbeiter m[]= {newnewnewnew Mitarbeiter("Egon"), Mitarbeiter("Egon"), Mitarbeiter("Egon"), Mitarbeiter("Egon"),

newnewnewnew MitarbeiterMitarbeiterMitarbeiterMitarbeiter("("("("AiseAiseAiseAise"), "), "), "), newnewnewnew Mitarbeiter("Urs")};Mitarbeiter("Urs")};Mitarbeiter("Urs")};Mitarbeiter("Urs")};em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();forforforfor ((((intintintint i=0; i<i=0; i<i=0; i<i=0; i<m.lengthm.lengthm.lengthm.length; i++); i++); i++); i++)

em.persistem.persistem.persistem.persist(m[i]);(m[i]);(m[i]);(m[i]);forforforfor (Projektauftrag p : (List<Projektauftrag>) (Projektauftrag p : (List<Projektauftrag>) (Projektauftrag p : (List<Projektauftrag>) (Projektauftrag p : (List<Projektauftrag>) emememem....

createQuerycreateQuerycreateQuerycreateQuery("SELECT p FROM Projektauftrag p").("SELECT p FROM Projektauftrag p").("SELECT p FROM Projektauftrag p").("SELECT p FROM Projektauftrag p").getResultListgetResultListgetResultListgetResultList())())())())

ifififif((((p.getTitelp.getTitelp.getTitelp.getTitel().().().().equalsequalsequalsequals("Analyse")){("Analyse")){("Analyse")){("Analyse")){m[0].m[0].m[0].m[0].auftragHinzuauftragHinzuauftragHinzuauftragHinzu(p);(p);(p);(p);p.setBearbeiterp.setBearbeiterp.setBearbeiterp.setBearbeiter(m[0]);(m[0]);(m[0]);(m[0]);

}}}}elseelseelseelse{{{{m[1].m[1].m[1].m[1].auftragHinzuauftragHinzuauftragHinzuauftragHinzu(p);(p);(p);(p);p.setBearbeiterp.setBearbeiterp.setBearbeiterp.setBearbeiter(m[1]);(m[1]);(m[1]);(m[1]);

} } } } em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();}}}}

JPA 1.0-Variante der

Anfrage

Page 52: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

192Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional 1:N (5/5)SELECT MITARBEITER.NAME, MITARBEITER.MINR, SELECT MITARBEITER.NAME, MITARBEITER.MINR, SELECT MITARBEITER.NAME, MITARBEITER.MINR, SELECT MITARBEITER.NAME, MITARBEITER.MINR,

PROJEKTAUFTRAG.TITEL, PROJEKTAUFTRAG.PAIDPROJEKTAUFTRAG.TITEL, PROJEKTAUFTRAG.PAIDPROJEKTAUFTRAG.TITEL, PROJEKTAUFTRAG.PAIDPROJEKTAUFTRAG.TITEL, PROJEKTAUFTRAG.PAID

FROM MITARBEITER LEFT JOIN PROJEKTAUFTRAGFROM MITARBEITER LEFT JOIN PROJEKTAUFTRAGFROM MITARBEITER LEFT JOIN PROJEKTAUFTRAGFROM MITARBEITER LEFT JOIN PROJEKTAUFTRAG

ON (MITARBEITER.MINR=PROJEKTAUFTRAG.BEARBEITER_MINR) ;ON (MITARBEITER.MINR=PROJEKTAUFTRAG.BEARBEITER_MINR) ;ON (MITARBEITER.MINR=PROJEKTAUFTRAG.BEARBEITER_MINR) ;ON (MITARBEITER.MINR=PROJEKTAUFTRAG.BEARBEITER_MINR) ;

Page 53: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

193Komponentenbasierte Software-Entwicklung

Umsetzung ist OR-Mapper freigestellt

Man sieht, dass bei bidirektionalen Beziehungen in EclipseLink keine neuen Tabellen angelegt werden, bei

unidirektionalen schon

Page 54: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

194Komponentenbasierte Software-Entwicklung

Wichtige Annotationen in Großprojekten

@Version @Version @Version @Version intintintint versionversionversionversion

• Attribut wird für das optimistische Locking genutzt; erst beim Schreiben geschaut, ob sich Versionsnummer geändert hat

• performant, wenn Objekte nicht häufig geändert werden

• Einfach als zusätzliches Attribut ergänzen@Basic(@Basic(@Basic(@Basic(fetchfetchfetchfetch====FetchType.LAZYFetchType.LAZYFetchType.LAZYFetchType.LAZY))))

private private private private Set<Projektauftrag> Set<Projektauftrag> Set<Projektauftrag> Set<Projektauftrag> auftraegeauftraegeauftraegeauftraege

• EAGER: Alle Daten des Attributs werden bei Objektnutzung sofort in Hauptspeicher geladen (default)

• LAZY: Daten werden erst geladen, wenn benötigt

• Längere Listen oder komplexe Daten möglichst immer LAZY (versteckte Konsistenzprobleme möglich)

• Wenn eine Info sofort benötigt, ist Kette zur Info EAGER

Page 55: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

195Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional M:N (1/6)

Page 56: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

196Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional M:N (2/6)

@Entity@Entity@Entity@Entity

public class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {public class Projektauftrag implements Serializable {

@Id @GeneratedValue @Id @GeneratedValue @Id @GeneratedValue @Id @GeneratedValue

private int paid;private int paid;private int paid;private int paid;

private String titel;private String titel;private String titel;private String titel;

@ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST,

CascadeType.MERGE})CascadeType.MERGE})CascadeType.MERGE})CascadeType.MERGE})

private Mitarbeiter bearbeiter;private Mitarbeiter bearbeiter;private Mitarbeiter bearbeiter;private Mitarbeiter bearbeiter;

@ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST, @ManyToOne(cascade={CascadeType.PERSIST,

CascadeType.MERGE})CascadeType.MERGE})CascadeType.MERGE})CascadeType.MERGE})

private Rolle rolle;private Rolle rolle;private Rolle rolle;private Rolle rolle;

@Version@Version@Version@Version

private int version;private int version;private int version;private int version;

Page 57: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

197Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional M:N (3/6)

@@@@EntityEntityEntityEntitypublicpublicpublicpublic classclassclassclass Rolle Rolle Rolle Rolle implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

@ID @@ID @@ID @@ID @GeneratedValueGeneratedValueGeneratedValueGeneratedValue private private private private intintintint ridridridrid;;;;private String private String private String private String namenamenamename;;;;private private private private intintintint tagessatztagessatztagessatztagessatz;;;;

@@@@ManyToManyManyToManyManyToManyManyToMany((((cascadecascadecascadecascade = {= {= {= {CascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSIST, , , , CascadeType.MERGECascadeType.MERGECascadeType.MERGECascadeType.MERGE})})})})

@Basic(@Basic(@Basic(@Basic(fetchfetchfetchfetch = = = = FetchType.LAZYFetchType.LAZYFetchType.LAZYFetchType.LAZY))))private List<Mitarbeiter> private List<Mitarbeiter> private List<Mitarbeiter> private List<Mitarbeiter> mitarbeitermitarbeitermitarbeitermitarbeiter;;;;

@Version private @Version private @Version private @Version private intintintint versionversionversionversion;;;;

publicpublicpublicpublic voidvoidvoidvoid mitarbeiterHinzumitarbeiterHinzumitarbeiterHinzumitarbeiterHinzu(Mitarbeiter m) {(Mitarbeiter m) {(Mitarbeiter m) {(Mitarbeiter m) {mitarbeiter.addmitarbeiter.addmitarbeiter.addmitarbeiter.add(m);(m);(m);(m);

}}}}

Page 58: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

198Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional M:N (4/6)

@@@@EntityEntityEntityEntitypublicpublicpublicpublic classclassclassclass Mitarbeiter Mitarbeiter Mitarbeiter Mitarbeiter implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

@@@@IdIdIdId @@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValue((((strategystrategystrategystrategy = = = = GenerationType.AUTOGenerationType.AUTOGenerationType.AUTOGenerationType.AUTO))))private private private private intintintint minrminrminrminr;;;;private String private String private String private String namenamenamename;;;;

@@@@OneToManyOneToManyOneToManyOneToMany((((mappedBymappedBymappedBymappedBy = "= "= "= "bearbeiterbearbeiterbearbeiterbearbeiter", ", ", ", cascadecascadecascadecascade = {= {= {= {CascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSIST, , , , CascadeType.MERGECascadeType.MERGECascadeType.MERGECascadeType.MERGE})})})})

@Basic(@Basic(@Basic(@Basic(fetchfetchfetchfetch = = = = FetchType.LAZYFetchType.LAZYFetchType.LAZYFetchType.LAZY))))private Set<Projektauftrag> private Set<Projektauftrag> private Set<Projektauftrag> private Set<Projektauftrag> auftraegeauftraegeauftraegeauftraege;;;;

@@@@ManyToManyManyToManyManyToManyManyToMany((((mappedBymappedBymappedBymappedBy = "= "= "= "mitarbeitermitarbeitermitarbeitermitarbeiter", ", ", ", cascadecascadecascadecascade = {= {= {= {CascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSIST, , , , CascadeType.MERGECascadeType.MERGECascadeType.MERGECascadeType.MERGE})})})})

@Basic(@Basic(@Basic(@Basic(fetchfetchfetchfetch = = = = FetchType.LAZYFetchType.LAZYFetchType.LAZYFetchType.LAZY))))private Set<Rolle> rollen = private Set<Rolle> rollen = private Set<Rolle> rollen = private Set<Rolle> rollen = newnewnewnew HashSetHashSetHashSetHashSet<Rolle<Rolle<Rolle<Rolle>();>();>();>();

@Version private @Version private @Version private @Version private intintintint versionversionversionversion;;;;

publicpublicpublicpublic voidvoidvoidvoid rolleHinzurolleHinzurolleHinzurolleHinzu(Rolle r) {(Rolle r) {(Rolle r) {(Rolle r) {rollen.addrollen.addrollen.addrollen.add(r(r(r(r););););

}}}}

Page 59: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

199Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional M:N (5/6)

publicpublicpublicpublic void void void void mitarbeiterZuordnenmitarbeiterZuordnenmitarbeiterZuordnenmitarbeiterZuordnen() {() {() {() {Mitarbeiter m[] = {Mitarbeiter m[] = {Mitarbeiter m[] = {Mitarbeiter m[] = {newnewnewnew Mitarbeiter("Egon"), Mitarbeiter("Egon"), Mitarbeiter("Egon"), Mitarbeiter("Egon"),

newnewnewnew MitarbeiterMitarbeiterMitarbeiterMitarbeiter("("("("AiseAiseAiseAise"), "), "), "), newnewnewnew Mitarbeiter("Urs")};Mitarbeiter("Urs")};Mitarbeiter("Urs")};Mitarbeiter("Urs")};em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();forforforfor ((((intintintint i = 0; i < i = 0; i < i = 0; i < i = 0; i < m.lengthm.lengthm.lengthm.length; i++) ; i++) ; i++) ; i++)

em.persistem.persistem.persistem.persist(m[i]);(m[i]);(m[i]);(m[i]);Rolle r[] = {Rolle r[] = {Rolle r[] = {Rolle r[] = {newnewnewnew Rolle("OOAD",80), Rolle("OOAD",80), Rolle("OOAD",80), Rolle("OOAD",80), newnewnewnew Rolle("SVN",60), Rolle("SVN",60), Rolle("SVN",60), Rolle("SVN",60),

newnewnewnew Rolle("QS",100)};Rolle("QS",100)};Rolle("QS",100)};Rolle("QS",100)};forforforfor ((((intintintint i = 0; i < i = 0; i < i = 0; i < i = 0; i < r.lengthr.lengthr.lengthr.length; i++) {; i++) {; i++) {; i++) {

forforforfor((((intintintint j = 0; j<j = 0; j<j = 0; j<j = 0; j<m.lengthm.lengthm.lengthm.length; ; ; ; j++j++j++j++))))ifififif(r[i].(r[i].(r[i].(r[i].getNamegetNamegetNamegetName().().().().lengthlengthlengthlength()<m[j].()<m[j].()<m[j].()<m[j].getNamegetNamegetNamegetName().().().().lengthlengthlengthlength()){()){()){()){r[i].r[i].r[i].r[i].mitarbeiterHinzumitarbeiterHinzumitarbeiterHinzumitarbeiterHinzu(m[j]);(m[j]);(m[j]);(m[j]);m[j].m[j].m[j].m[j].rolleHinzurolleHinzurolleHinzurolleHinzu(r[i]);(r[i]);(r[i]);(r[i]);

}}}}em.persistem.persistem.persistem.persist(r[i]);(r[i]);(r[i]);(r[i]);

}}}}// Rollenzuordnung wie bei 1:N // Rollenzuordnung wie bei 1:N // Rollenzuordnung wie bei 1:N // Rollenzuordnung wie bei 1:N mitarbeiterZuordnenmitarbeiterZuordnenmitarbeiterZuordnenmitarbeiterZuordnen()()()()em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();

}}}}

Page 60: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

200Komponentenbasierte Software-Entwicklung

Umsetzung bidirektional M:N (6/6)

Page 61: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

201Komponentenbasierte Software-Entwicklung

Tabellenstruktur

Page 62: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

202Komponentenbasierte Software-Entwicklung

Ungeordnete Daten (1/4)

@Entity@Entity@Entity@Entitypublic class Punkt implements Serializable{public class Punkt implements Serializable{public class Punkt implements Serializable{public class Punkt implements Serializable{@Id @GeneratedValue@Id @GeneratedValue@Id @GeneratedValue@Id @GeneratedValueprivate int id;private int id;private int id;private int id;private int x;private int x;private int x;private int x;private int y;private int y;private int y;private int y;@Version@Version@Version@Versionprivate int version;private int version;private int version;private int version;

public Punkt(int x, int y) {public Punkt(int x, int y) {public Punkt(int x, int y) {public Punkt(int x, int y) {this.x = x;this.x = x;this.x = x;this.x = x;this.y = y;this.y = y;this.y = y;this.y = y;

}}}}

public Punkt(){}public Punkt(){}public Punkt(){}public Punkt(){}

@Override@Override@Override@Overridepublic String toString(){public String toString(){public String toString(){public String toString(){return "["+x+","+y+"]";return "["+x+","+y+"]";return "["+x+","+y+"]";return "["+x+","+y+"]";

}}}}// get// get// get// get---- und setund setund setund set----Methoden für ExemplarvariablenMethoden für ExemplarvariablenMethoden für ExemplarvariablenMethoden für Exemplarvariablen

Problem: Auch Listen werden ungeordnet gespeichert

Page 63: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

203Komponentenbasierte Software-Entwicklung

Ungeordnete Daten (2/4)

@Entity@Entity@Entity@Entitypublicpublicpublicpublic classclassclassclass Polygon Polygon Polygon Polygon implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable{{{{@@@@IdIdIdId @@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValueprivate private private private intintintint idididid;;;;@@@@OneToManyOneToManyOneToManyOneToMany((((cascadecascadecascadecascade = {= {= {= {CascadeType.ALLCascadeType.ALLCascadeType.ALLCascadeType.ALL})})})})private List<Punkt> punkte= private List<Punkt> punkte= private List<Punkt> punkte= private List<Punkt> punkte= newnewnewnew ArrayListArrayListArrayListArrayList<Punkt>();<Punkt>();<Punkt>();<Punkt>();@Version private @Version private @Version private @Version private intintintint versionversionversionversion;;;;

publicpublicpublicpublic Polygon(){} //Polygon(){} //Polygon(){} //Polygon(){} //getgetgetget und und und und setsetsetset für Exemplarvariablenfür Exemplarvariablenfür Exemplarvariablenfür Exemplarvariablen

publicpublicpublicpublic void void void void punkteHinzupunkteHinzupunkteHinzupunkteHinzu(Punkt... (Punkt... (Punkt... (Punkt... pktepktepktepkte){){){){forforforfor(Punkt p:pkte)(Punkt p:pkte)(Punkt p:pkte)(Punkt p:pkte)punkte.addpunkte.addpunkte.addpunkte.add(p);(p);(p);(p);

}}}}

@@@@OverrideOverrideOverrideOverride publicpublicpublicpublic String String String String toStringtoStringtoStringtoString(){(){(){(){StringBufferStringBufferStringBufferStringBuffer ergergergerg====newnewnewnew StringBufferStringBufferStringBufferStringBuffer("<");("<");("<");("<");forforforfor(Punkt p:punkte)(Punkt p:punkte)(Punkt p:punkte)(Punkt p:punkte)erg.appenderg.appenderg.appenderg.append((((p.toStringp.toStringp.toStringp.toString());());());());

returnreturnreturnreturn erg.appenderg.appenderg.appenderg.append(">").(">").(">").(">").toStringtoStringtoStringtoString();();();();}}}}

Page 64: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

204Komponentenbasierte Software-Entwicklung

Ungeordnete Daten (3/4)

publicpublicpublicpublic classclassclassclass Main {Main {Main {Main {private private private private EntityManagerFactoryEntityManagerFactoryEntityManagerFactoryEntityManagerFactory emfemfemfemf ====Persistence.createEntityManagerFactoryPersistence.createEntityManagerFactoryPersistence.createEntityManagerFactoryPersistence.createEntityManagerFactory("JPA20NeueFeaturesPU");("JPA20NeueFeaturesPU");("JPA20NeueFeaturesPU");("JPA20NeueFeaturesPU");private private private private EntityManagerEntityManagerEntityManagerEntityManager emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager();();();();

publicpublicpublicpublic voidvoidvoidvoid objekteErzeugenobjekteErzeugenobjekteErzeugenobjekteErzeugen(){(){(){(){Punkt[] Punkt[] Punkt[] Punkt[] pktpktpktpkt={={={={newnewnewnew Punkt(0,0), Punkt(0,0), Punkt(0,0), Punkt(0,0), newnewnewnew Punkt(5,3), Punkt(5,3), Punkt(5,3), Punkt(5,3),

newnewnewnew Punkt(3,3), Punkt(3,3), Punkt(3,3), Punkt(3,3), newnewnewnew Punkt(3,0)};Punkt(3,0)};Punkt(3,0)};Punkt(3,0)};em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();forforforfor(Punkt p:pkt)(Punkt p:pkt)(Punkt p:pkt)(Punkt p:pkt)em.persistem.persistem.persistem.persist(p);(p);(p);(p);

em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();Polygon p1 = Polygon p1 = Polygon p1 = Polygon p1 = newnewnewnew Polygon();Polygon();Polygon();Polygon();p1.punkteHinzu(p1.punkteHinzu(p1.punkteHinzu(p1.punkteHinzu(pktpktpktpkt[0],[0],[0],[0],pktpktpktpkt[1],[1],[1],[1],pktpktpktpkt[2]);[2]);[2]);[2]);Polygon p2 = Polygon p2 = Polygon p2 = Polygon p2 = newnewnewnew Polygon();Polygon();Polygon();Polygon();p2.punkteHinzu(p2.punkteHinzu(p2.punkteHinzu(p2.punkteHinzu(pktpktpktpkt[3],[3],[3],[3],pktpktpktpkt[2],[2],[2],[2],pktpktpktpkt[1]);[1]);[1]);[1]);em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();em.persistem.persistem.persistem.persist(p1);(p1);(p1);(p1);em.persistem.persistem.persistem.persist(p2(p2(p2(p2););););em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();

}}}}

Page 65: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

205Komponentenbasierte Software-Entwicklung

Ungeordnete Daten (4/4)

publicpublicpublicpublic voidvoidvoidvoid zeigePolygonezeigePolygonezeigePolygonezeigePolygone(){(){(){(){List<Polygon> List<Polygon> List<Polygon> List<Polygon> plplplpl = = = = em.createQueryem.createQueryem.createQueryem.createQuery(((("SELECT p FROM Polygon p","SELECT p FROM Polygon p","SELECT p FROM Polygon p","SELECT p FROM Polygon p",Polygon.classPolygon.classPolygon.classPolygon.class).).).).getResultListgetResultListgetResultListgetResultList();();();();

forforforfor(Polygon (Polygon (Polygon (Polygon po:plpo:plpo:plpo:pl))))System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((popopopo););););

}}}}

publicpublicpublicpublic voidvoidvoidvoid schliessenschliessenschliessenschliessen() {() {() {() {ifififif ((((emememem != null && != null && != null && != null && em.isOpenem.isOpenem.isOpenem.isOpen()) ()) ()) ()) em.closeem.closeem.closeem.close();();();();ifififif ((((emfemfemfemf != null && != null && != null && != null && emf.isOpenemf.isOpenemf.isOpenemf.isOpen()) ()) ()) ()) emf.closeemf.closeemf.closeemf.close();();();();

}}}}

publicpublicpublicpublic staticstaticstaticstatic voidvoidvoidvoid mainmainmainmain(String[] (String[] (String[] (String[] argsargsargsargs) {) {) {) {Main m= Main m= Main m= Main m= newnewnewnew Main();Main();Main();Main();m.objekteErzeugenm.objekteErzeugenm.objekteErzeugenm.objekteErzeugen();();();();m.zeigePolygonem.zeigePolygonem.zeigePolygonem.zeigePolygone();();();();m.schliessenm.schliessenm.schliessenm.schliessen();();();();System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println("("("("----------------");");");");m= m= m= m= newnewnewnew Main();Main();Main();Main();m.zeigePolygonem.zeigePolygonem.zeigePolygonem.zeigePolygone();();();();m.schliessenm.schliessenm.schliessenm.schliessen();();();();

}}}}}}}}

<[0,0][5,3][3,3]> <[0,0][5,3][3,3]> <[0,0][5,3][3,3]> <[0,0][5,3][3,3]> <[3,0][3,3][5,3]><[3,0][3,3][5,3]><[3,0][3,3][5,3]><[3,0][3,3][5,3]>

----------------<[0,0][5,3][3,3]> <[0,0][5,3][3,3]> <[0,0][5,3][3,3]> <[0,0][5,3][3,3]> <[5,3][3,3][3,0]><[5,3][3,3][3,0]><[5,3][3,3][3,0]><[5,3][3,3][3,0]>

Page 66: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

206Komponentenbasierte Software-Entwicklung

Ordnung beibehalten

@Entity@Entity@Entity@Entitypublicpublicpublicpublic classclassclassclass Polygon Polygon Polygon Polygon implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable{{{{@@@@IdIdIdId @@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValueprivate private private private intintintint idididid;;;;@@@@OneToManyOneToManyOneToManyOneToMany((((cascadecascadecascadecascade = {= {= {= {CascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSIST, , , , CascadeType.MERGECascadeType.MERGECascadeType.MERGECascadeType.MERGE})})})})@@@@OrderColumnOrderColumnOrderColumnOrderColumn((((namenamenamename="="="="OrdOrdOrdOrd")")")")private List<Punkt> punkte= private List<Punkt> punkte= private List<Punkt> punkte= private List<Punkt> punkte= newnewnewnew ArrayListArrayListArrayListArrayList<Punkt>();<Punkt>();<Punkt>();<Punkt>();@Version@Version@Version@Versionprivate private private private intintintint versionversionversionversion;;;;

Hinweis: persistence.xml mit create

<[3,0][3,3][5,3]><[3,0][3,3][5,3]><[3,0][3,3][5,3]><[3,0][3,3][5,3]><[0,0][5,3][3,3]><[0,0][5,3][3,3]><[0,0][5,3][3,3]><[0,0][5,3][3,3]>----------------<[3,0][3,3][5,3]><[3,0][3,3][5,3]><[3,0][3,3][5,3]><[3,0][3,3][5,3]><[0,0][5,3][3,3]><[0,0][5,3][3,3]><[0,0][5,3][3,3]><[0,0][5,3][3,3]>

Page 67: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

207Komponentenbasierte Software-Entwicklung

Standard: keine Löschfortsetzung (1/2)

publicpublicpublicpublic void void void void objekteErzeugenobjekteErzeugenobjekteErzeugenobjekteErzeugen() {() {() {() {Punkt[] Punkt[] Punkt[] Punkt[] pktpktpktpkt = {= {= {= {newnewnewnew Punkt(0, 0), Punkt(0, 0), Punkt(0, 0), Punkt(0, 0), newnewnewnew Punkt(5, 3), Punkt(5, 3), Punkt(5, 3), Punkt(5, 3),

newnewnewnew Punkt(3, 3)};Punkt(3, 3)};Punkt(3, 3)};Punkt(3, 3)};Polygon p1 = Polygon p1 = Polygon p1 = Polygon p1 = newnewnewnew Polygon();Polygon();Polygon();Polygon();p1.punkteHinzu(p1.punkteHinzu(p1.punkteHinzu(p1.punkteHinzu(pktpktpktpkt[0], [0], [0], [0], pktpktpktpkt[1], [1], [1], [1], pktpktpktpkt[2]);[2]);[2]);[2]);em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();em.persistem.persistem.persistem.persist(p1);(p1);(p1);(p1);em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();

}}}}

publicpublicpublicpublic void void void void objekteBearbeitenobjekteBearbeitenobjekteBearbeitenobjekteBearbeiten() {() {() {() {Polygon Polygon Polygon Polygon plplplpl = = = = em.createQueryem.createQueryem.createQueryem.createQuery("SELECT p FROM Polygon p", ("SELECT p FROM Polygon p", ("SELECT p FROM Polygon p", ("SELECT p FROM Polygon p",

Polygon.classPolygon.classPolygon.classPolygon.class).).).).getResultListgetResultListgetResultListgetResultList().().().().getgetgetget(0);(0);(0);(0);pl.getPunktepl.getPunktepl.getPunktepl.getPunkte().().().().removeremoveremoveremove(1);(1);(1);(1);em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();em.persistem.persistem.persistem.persist((((plplplpl););););em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();

}}}}

Page 68: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

208Komponentenbasierte Software-Entwicklung

Standard: keine Löschfortsetzung (2/2)

publicpublicpublicpublic void void void void zeigePolygoneUndPunktezeigePolygoneUndPunktezeigePolygoneUndPunktezeigePolygoneUndPunkte() {() {() {() {forforforfor (Polygon (Polygon (Polygon (Polygon popopopo : : : : em.createQueryem.createQueryem.createQueryem.createQuery("SELECT p FROM Polygon p", ("SELECT p FROM Polygon p", ("SELECT p FROM Polygon p", ("SELECT p FROM Polygon p",

Polygon.classPolygon.classPolygon.classPolygon.class).).).).getResultListgetResultListgetResultListgetResultList())())())())System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((popopopo););););

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println("("("("----------------");");");");forforforfor (Punkt (Punkt (Punkt (Punkt pupupupu : : : : em.createQueryem.createQueryem.createQueryem.createQuery("SELECT p FROM Punkt p", ("SELECT p FROM Punkt p", ("SELECT p FROM Punkt p", ("SELECT p FROM Punkt p",

Punkt.classPunkt.classPunkt.classPunkt.class).).).).getResultListgetResultListgetResultListgetResultList()) ()) ()) ()) System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((pupupupu););););

}}}}

publicpublicpublicpublic staticstaticstaticstatic void void void void mainmainmainmain(String[] (String[] (String[] (String[] argsargsargsargs) {) {) {) {Main m = Main m = Main m = Main m = newnewnewnew Main();Main();Main();Main();m.objekteErzeugenm.objekteErzeugenm.objekteErzeugenm.objekteErzeugen();();();();m.objekteBearbeitenm.objekteBearbeitenm.objekteBearbeitenm.objekteBearbeiten();();();();m.zeigePolygoneUndPunktem.zeigePolygoneUndPunktem.zeigePolygoneUndPunktem.zeigePolygoneUndPunkte();();();();m.schliessenm.schliessenm.schliessenm.schliessen();();();();

}}}}

<[0,0][3,3]><[0,0][3,3]><[0,0][3,3]><[0,0][3,3]>----------------[0,0][0,0][0,0][0,0][5,3][5,3][5,3][5,3][3,3][3,3][3,3][3,3]

Page 69: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

209Komponentenbasierte Software-Entwicklung

Löschfortsetzung

• Anmerkung: auch keine Löschung alleine durch CASCADETYPE.ALLCASCADETYPE.ALLCASCADETYPE.ALLCASCADETYPE.ALL

in Polygon, aber durch folgende Ergänzung

@@@@OneToManyOneToManyOneToManyOneToMany((((cascadecascadecascadecascade = {= {= {= {CascadeType.ALLCascadeType.ALLCascadeType.ALLCascadeType.ALL}, }, }, },

orphanRemovalorphanRemovalorphanRemovalorphanRemoval====truetruetruetrue))))

@@@@OrderColumnOrderColumnOrderColumnOrderColumn((((namenamenamename="="="="OrdOrdOrdOrd")")")")

private List<Punkt> punkte = private List<Punkt> punkte = private List<Punkt> punkte = private List<Punkt> punkte =

newnewnewnew ArrayListArrayListArrayListArrayList<Punkt>();<Punkt>();<Punkt>();<Punkt>();

• Was passiert, wenn mehrere Objekte Punkt referenzieren (widerspricht der Eigentümerschaft)?

Exception Exception Exception Exception in thread "main“ in thread "main“ in thread "main“ in thread "main“ javax.persistence.RollbackExceptionjavax.persistence.RollbackExceptionjavax.persistence.RollbackExceptionjavax.persistence.RollbackException

CausedCausedCausedCaused bybybyby: : : : java.sql.SQLIntegrityConstraintViolationExceptionjava.sql.SQLIntegrityConstraintViolationExceptionjava.sql.SQLIntegrityConstraintViolationExceptionjava.sql.SQLIntegrityConstraintViolationException: : : : DELETE in Tabelle 'PUNKT' hat für Schlüssel (3) die DELETE in Tabelle 'PUNKT' hat für Schlüssel (3) die DELETE in Tabelle 'PUNKT' hat für Schlüssel (3) die DELETE in Tabelle 'PUNKT' hat für Schlüssel (3) die Integritätsbedingung 'PLYGONPUNKTPNKTEID' für Fremdschlüssel Integritätsbedingung 'PLYGONPUNKTPNKTEID' für Fremdschlüssel Integritätsbedingung 'PLYGONPUNKTPNKTEID' für Fremdschlüssel Integritätsbedingung 'PLYGONPUNKTPNKTEID' für Fremdschlüssel verletzt.verletzt.verletzt.verletzt.

<[0,0][3,3]><[0,0][3,3]><[0,0][3,3]><[0,0][3,3]>----------------[0,0][0,0][0,0][0,0][3,3][3,3][3,3][3,3]

Page 70: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

210Komponentenbasierte Software-Entwicklung

Beispieldaten (in DB-Notation)

Mitarbeiter

Projekt

Rolle

Projektauftrag

Projekt_Projektauftrag

Page 71: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

211Komponentenbasierte Software-Entwicklung

Anfragen

• Anfragesprache soll möglichst Entity-Objekte liefern

• Anfragesprache soll DB-unabhängig sein (SQL-Detailproblem)

• Antwort: Java Persistence QL (JPQL)

– Ermöglicht direkte Zurückgabe von Entitätsobjektlisten

– Ermöglicht auch direkte Ausführung von SQL-Anfragen

• Anmerkung: Vorgänger JDO unterstützte OO-Features in JDO-QL (Methodennutzung); dies ist nicht mehr möglich

• Typische Struktur:

– SELECT p FROM Projekt p WHERE <Bed>SELECT p FROM Projekt p WHERE <Bed>SELECT p FROM Projekt p WHERE <Bed>SELECT p FROM Projekt p WHERE <Bed>

– Übersetzung: Wähle aus der Menge Projekt der gemanageten Objekte die Elemente p mit Eigenschaft <Bed>

Page 72: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

212Komponentenbasierte Software-Entwicklung

Anfrageausführung

• Setzt ordentliches toString() voraus

• ist nicht typsicherpublicpublicpublicpublic voidvoidvoidvoid anfragen(String anfragen(String anfragen(String anfragen(String qlqlqlql) {) {) {) {

trytrytrytry {{{{

Query Query Query Query queryqueryqueryquery = = = = em.createQueryem.createQueryem.createQueryem.createQuery((((qlqlqlql););););

CollectionCollectionCollectionCollection ergergergerg = = = = query.getResultListquery.getResultListquery.getResultListquery.getResultList();();();();

forforforfor ((((IteratorIteratorIteratorIterator itititit = = = = erg.iteratorerg.iteratorerg.iteratorerg.iterator(); (); (); (); it.hasNextit.hasNextit.hasNextit.hasNext();) {();) {();) {();) {

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((it.nextit.nextit.nextit.next());());());());

}}}}

} catch (Exception e) {} catch (Exception e) {} catch (Exception e) {} catch (Exception e) {

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println("Anfrage gescheitert: " ("Anfrage gescheitert: " ("Anfrage gescheitert: " ("Anfrage gescheitert: "

+ + + + e.getMessagee.getMessagee.getMessagee.getMessage());());());());

}}}}

}}}}

Page 73: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

213Komponentenbasierte Software-Entwicklung

Einfache Beispiele

Vorbemerkung: In FROM-Zeilen stehen Klassen und Attributnamen; bei diesen muss Groß- und Kleinschreibung beachtet werden!

SELECT p FROM Projekt pSELECT p FROM Projekt pSELECT p FROM Projekt pSELECT p FROM Projekt p

• Projekt Projekt Projekt Projekt BonitaetBonitaetBonitaetBonitaet ((((5555) ) ) ) [Konten Historie Raten ][Konten Historie Raten ][Konten Historie Raten ][Konten Historie Raten ]

• Projekt Bremse Projekt Bremse Projekt Bremse Projekt Bremse (11) (11) (11) (11) [Display Sensoren Fusion ][Display Sensoren Fusion ][Display Sensoren Fusion ][Display Sensoren Fusion ]

Direkter Zugriff auf Attribute

SELECT p.name FROM Projekt pSELECT p.name FROM Projekt pSELECT p.name FROM Projekt pSELECT p.name FROM Projekt p

• BonitaetBonitaetBonitaetBonitaet

• BremseBremseBremseBremse

Page 74: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

214Komponentenbasierte Software-Entwicklung

Nutzung mehrwertiger Relationen (1/2)

SELECT SELECT SELECT SELECT p.auftraegep.auftraegep.auftraegep.auftraege FROM Projekt pFROM Projekt pFROM Projekt pFROM Projekt p

• Aufgabe Raten Aufgabe Raten Aufgabe Raten Aufgabe Raten (10) (10) (10) (10) durch Ivan als Javadurch Ivan als Javadurch Ivan als Javadurch Ivan als Java

• Aufgabe Konten Aufgabe Konten Aufgabe Konten Aufgabe Konten ((((6666) ) ) ) durch Fatma als Coboldurch Fatma als Coboldurch Fatma als Coboldurch Fatma als Cobol

• Aufgabe Historie Aufgabe Historie Aufgabe Historie Aufgabe Historie ((((8888) ) ) ) durch Urs als Javadurch Urs als Javadurch Urs als Javadurch Urs als Java

• Aufgabe Sensoren Aufgabe Sensoren Aufgabe Sensoren Aufgabe Sensoren (12) (12) (12) (12) durch Ivan als Cdurch Ivan als Cdurch Ivan als Cdurch Ivan als C

• Aufgabe Display Aufgabe Display Aufgabe Display Aufgabe Display (14) (14) (14) (14) durch Fatma als Javadurch Fatma als Javadurch Fatma als Javadurch Fatma als Java

• Aufgabe Fusion Aufgabe Fusion Aufgabe Fusion Aufgabe Fusion (15) (15) (15) (15) durch Ivan als Cdurch Ivan als Cdurch Ivan als Cdurch Ivan als C

Nicht erlaubt:

SELECT SELECT SELECT SELECT p.auftraege.bearbeiterp.auftraege.bearbeiterp.auftraege.bearbeiterp.auftraege.bearbeiter FROM Projekt pFROM Projekt pFROM Projekt pFROM Projekt p

• An exception occurred while creating a query in An exception occurred while creating a query in An exception occurred while creating a query in An exception occurred while creating a query in EntityManagerEntityManagerEntityManagerEntityManager::::

Exception Exception Exception Exception Description: Error compiling the query [SELECT Description: Error compiling the query [SELECT Description: Error compiling the query [SELECT Description: Error compiling the query [SELECT p.auftraege.bearbeiterp.auftraege.bearbeiterp.auftraege.bearbeiterp.auftraege.bearbeiter FROM FROM FROM FROM ProjektProjektProjektProjekt p], line 1, column 9: p], line 1, column 9: p], line 1, column 9: p], line 1, column 9: invalid navigation expression [invalid navigation expression [invalid navigation expression [invalid navigation expression [p.auftraege.bearbeiterp.auftraege.bearbeiterp.auftraege.bearbeiterp.auftraege.bearbeiter], cannot ], cannot ], cannot ], cannot navigate collection valued association field [navigate collection valued association field [navigate collection valued association field [navigate collection valued association field [auftraegeauftraegeauftraegeauftraege].].].].

Page 75: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

215Komponentenbasierte Software-Entwicklung

Nutzung mehrwertiger Relationen (2/2)

SELECT SELECT SELECT SELECT pa.bearbeiterpa.bearbeiterpa.bearbeiterpa.bearbeiter FROM Projektauftrag FROM Projektauftrag FROM Projektauftrag FROM Projektauftrag papapapa

1: Ivan 1: Ivan 1: Ivan 1: Ivan AuftraegeAuftraegeAuftraegeAuftraege=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]

Rollen=[ C Java ]Rollen=[ C Java ]Rollen=[ C Java ]Rollen=[ C Java ]

1: Ivan 1: Ivan 1: Ivan 1: Ivan AuftraegeAuftraegeAuftraegeAuftraege=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]

Rollen=[ C Java ]Rollen=[ C Java ]Rollen=[ C Java ]Rollen=[ C Java ]

1: Ivan 1: Ivan 1: Ivan 1: Ivan AuftraegeAuftraegeAuftraegeAuftraege=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]=[ Sensoren Fusion Raten ]

Rollen=[ C Java ]Rollen=[ C Java ]Rollen=[ C Java ]Rollen=[ C Java ]

2222: : : : Fatma Fatma Fatma Fatma AuftraegeAuftraegeAuftraegeAuftraege=[ Konten Display ]=[ Konten Display ]=[ Konten Display ]=[ Konten Display ]

Rollen=[ Cobol Java ]Rollen=[ Cobol Java ]Rollen=[ Cobol Java ]Rollen=[ Cobol Java ]

2222: : : : Fatma Fatma Fatma Fatma AuftraegeAuftraegeAuftraegeAuftraege=[ Konten Display ]=[ Konten Display ]=[ Konten Display ]=[ Konten Display ]

Rollen=[ Cobol Java ]Rollen=[ Cobol Java ]Rollen=[ Cobol Java ]Rollen=[ Cobol Java ]

3333: : : : Urs Urs Urs Urs AuftraegeAuftraegeAuftraegeAuftraege=[ Historie ]=[ Historie ]=[ Historie ]=[ Historie ]

Rollen=[ Java ]Rollen=[ Java ]Rollen=[ Java ]Rollen=[ Java ]

Page 76: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

216Komponentenbasierte Software-Entwicklung

Neu zusammengesetzte Ergebnisse

• Folgende Folie zeigt woher Details der Ausgabe kommen

SELECT r.name, SELECT r.name, SELECT r.name, SELECT r.name, r.tagessatzr.tagessatzr.tagessatzr.tagessatz FROM Rolle rFROM Rolle rFROM Rolle rFROM Rolle r

• [[[[Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;@1db5ec :: [;@1db5ec :: [;@1db5ec :: [;@1db5ec :: [Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;;;;

CCCC

50505050

• [[[[Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;@92b1a1 :: [;@92b1a1 :: [;@92b1a1 :: [;@92b1a1 :: [Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;;;;

JavaJavaJavaJava

60606060

• [[[[Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;@cbf9bd :: [;@cbf9bd :: [;@cbf9bd :: [;@cbf9bd :: [Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;;;;

CobolCobolCobolCobol

70707070

Page 77: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

217Komponentenbasierte Software-Entwicklung

Ausgabe mit detaillierterer Analyse

public void anfragen2(String ql) {public void anfragen2(String ql) {public void anfragen2(String ql) {public void anfragen2(String ql) {System.out.println(ql);System.out.println(ql);System.out.println(ql);System.out.println(ql);try {try {try {try {Query query = em.createQuery(ql);Query query = em.createQuery(ql);Query query = em.createQuery(ql);Query query = em.createQuery(ql);Collection erg = query.getResultList();Collection erg = query.getResultList();Collection erg = query.getResultList();Collection erg = query.getResultList();for (Iterator it = erg.iterator(); it.hasNext();) {for (Iterator it = erg.iterator(); it.hasNext();) {for (Iterator it = erg.iterator(); it.hasNext();) {for (Iterator it = erg.iterator(); it.hasNext();) {Object o = it.next();Object o = it.next();Object o = it.next();Object o = it.next();System.out.println(o+" :: "+ o.getClass().getName());System.out.println(o+" :: "+ o.getClass().getName());System.out.println(o+" :: "+ o.getClass().getName());System.out.println(o+" :: "+ o.getClass().getName());if(o.getClass().getName().equals("[Ljava.lang.Object;")){if(o.getClass().getName().equals("[Ljava.lang.Object;")){if(o.getClass().getName().equals("[Ljava.lang.Object;")){if(o.getClass().getName().equals("[Ljava.lang.Object;")){Object oa[]= (Object[]) o;Object oa[]= (Object[]) o;Object oa[]= (Object[]) o;Object oa[]= (Object[]) o;for(int i=0;i<oa.length;i++)for(int i=0;i<oa.length;i++)for(int i=0;i<oa.length;i++)for(int i=0;i<oa.length;i++)System.out.println(" "+oa[i]);System.out.println(" "+oa[i]);System.out.println(" "+oa[i]);System.out.println(" "+oa[i]);

}}}}}}}}

} catch (Exception e) {} catch (Exception e) {} catch (Exception e) {} catch (Exception e) {System.out.println("Anfragefehler: " + e.getMessage());System.out.println("Anfragefehler: " + e.getMessage());System.out.println("Anfragefehler: " + e.getMessage());System.out.println("Anfragefehler: " + e.getMessage());

}}}}}}}}

Page 78: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

218Komponentenbasierte Software-Entwicklung

JOIN-Varianten

SELECT m.name SELECT m.name SELECT m.name SELECT m.name

FROM Projektauftrag FROM Projektauftrag FROM Projektauftrag FROM Projektauftrag papapapa, Mitarbeiter m , Mitarbeiter m , Mitarbeiter m , Mitarbeiter m

WHERE WHERE WHERE WHERE pa.bearbeiterpa.bearbeiterpa.bearbeiterpa.bearbeiter=m =m =m =m

AND AND AND AND pa.titelpa.titelpa.titelpa.titel='Sensoren'='Sensoren'='Sensoren'='Sensoren'

SELECT m.name SELECT m.name SELECT m.name SELECT m.name

FROM Projektauftrag FROM Projektauftrag FROM Projektauftrag FROM Projektauftrag papapapa JOIN JOIN JOIN JOIN pa.bearbeiterpa.bearbeiterpa.bearbeiterpa.bearbeiter m m m m

WHERE WHERE WHERE WHERE pa.titelpa.titelpa.titelpa.titel='Sensoren'='Sensoren'='Sensoren'='Sensoren'

• IvanIvanIvanIvan

SELECT DISTINCT(pa.bearbeiter.name) SELECT DISTINCT(pa.bearbeiter.name) SELECT DISTINCT(pa.bearbeiter.name) SELECT DISTINCT(pa.bearbeiter.name)

FROM Projekt p JOIN FROM Projekt p JOIN FROM Projekt p JOIN FROM Projekt p JOIN p.auftraegep.auftraegep.auftraegep.auftraege papapapa

WHERE p.name='Bremse'WHERE p.name='Bremse'WHERE p.name='Bremse'WHERE p.name='Bremse'

• FatmaFatmaFatmaFatma

• IvanIvanIvanIvan

Page 79: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

219Komponentenbasierte Software-Entwicklung

Vordefinierte Anfragen + typisches Problem

private static final String PROJEKT_VON=private static final String PROJEKT_VON=private static final String PROJEKT_VON=private static final String PROJEKT_VON="SELECT DISTINCT(p.name) " "SELECT DISTINCT(p.name) " "SELECT DISTINCT(p.name) " "SELECT DISTINCT(p.name) " +"FROM Projekt p JOIN p.auftraege pa " +"FROM Projekt p JOIN p.auftraege pa " +"FROM Projekt p JOIN p.auftraege pa " +"FROM Projekt p JOIN p.auftraege pa " +"WHERE pa.bearbeiter.name= :mname";+"WHERE pa.bearbeiter.name= :mname";+"WHERE pa.bearbeiter.name= :mname";+"WHERE pa.bearbeiter.name= :mname";

public void projektVon(String name){public void projektVon(String name){public void projektVon(String name){public void projektVon(String name){Query query = em.createQuery(PROJEKT_VON).Query query = em.createQuery(PROJEKT_VON).Query query = em.createQuery(PROJEKT_VON).Query query = em.createQuery(PROJEKT_VON).

setParameter("mname", name);setParameter("mname", name);setParameter("mname", name);setParameter("mname", name);Collection erg = query.getResultList();Collection erg = query.getResultList();Collection erg = query.getResultList();Collection erg = query.getResultList();for (Iterator it = erg.iterator(); it.hasNext();) {for (Iterator it = erg.iterator(); it.hasNext();) {for (Iterator it = erg.iterator(); it.hasNext();) {for (Iterator it = erg.iterator(); it.hasNext();) {System.out.println(it.next());System.out.println(it.next());System.out.println(it.next());System.out.println(it.next());

}}}}}}}}

projektVon("Urs' OR NOT(p.name='bla') OR p.name='bla")projektVon("Urs' OR NOT(p.name='bla') OR p.name='bla")projektVon("Urs' OR NOT(p.name='bla') OR p.name='bla")projektVon("Urs' OR NOT(p.name='bla') OR p.name='bla")• BremseBremseBremseBremse• BonitaetBonitaetBonitaetBonitaet

Page 80: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

220Komponentenbasierte Software-Entwicklung

echte Standardkonformität?

• gerade bei Anfragen häufig keine 100%-Kompatibilität

• Hibernate meist etwas mächtiger als EclipseLink

• Beispiel: Zeige alle C-Programmierer

• geht:

SELECT SELECT SELECT SELECT m FROM m FROM m FROM m FROM RolleRolleRolleRolle r JOIN r JOIN r JOIN r JOIN r.mitarbeiterr.mitarbeiterr.mitarbeiterr.mitarbeiter m WHERE r.name='C‘m WHERE r.name='C‘m WHERE r.name='C‘m WHERE r.name='C‘

[[[[1: Ivan...1: Ivan...1: Ivan...1: Ivan...

• ging lange Zeit nicht in EclipseLink:

SELECT SELECT SELECT SELECT m FROM m FROM m FROM m FROM MitarbeiterMitarbeiterMitarbeiterMitarbeiter m JOIN m JOIN m JOIN m JOIN m.rollenm.rollenm.rollenm.rollen r WHERE r.name='C'r WHERE r.name='C'r WHERE r.name='C'r WHERE r.name='C'

invalid invalid invalid invalid navigation expression [r.name], cannot navigate navigation expression [r.name], cannot navigate navigation expression [r.name], cannot navigate navigation expression [r.name], cannot navigate expression [r] of type [expression [r] of type [expression [r] of type [expression [r] of type [java.util.Listjava.util.Listjava.util.Listjava.util.List] inside a query.] inside a query.] inside a query.] inside a query.

• trotzdem: Immer sinnvoll Objektauswahlen in Anfragesprache durchzuführen, nicht alle Objekte aus DB lutschen und dann verarbeiten

Page 81: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

221Komponentenbasierte Software-Entwicklung

Klassische SQL-Operatoren

SELECT p.name, COUNT(SELECT p.name, COUNT(SELECT p.name, COUNT(SELECT p.name, COUNT(pa.titelpa.titelpa.titelpa.titel) ) ) )

FROM Projekt p JOIN FROM Projekt p JOIN FROM Projekt p JOIN FROM Projekt p JOIN p.auftraegep.auftraegep.auftraegep.auftraege papapapa

GROUP BY p.nameGROUP BY p.nameGROUP BY p.nameGROUP BY p.name

• [[[[Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;@4a9a7d :: [;@4a9a7d :: [;@4a9a7d :: [;@4a9a7d :: [Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;;;;

BonitaetBonitaetBonitaetBonitaet

3333

• [[[[Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;@1e4a47e :: [;@1e4a47e :: [;@1e4a47e :: [;@1e4a47e :: [Ljava.lang.ObjectLjava.lang.ObjectLjava.lang.ObjectLjava.lang.Object;;;;

BremseBremseBremseBremse

3333

• Erinnerung AVG, SUM, MIN, MAX

Page 82: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

222Komponentenbasierte Software-Entwicklung

Named Queries

@@@@NamedQueriesNamedQueriesNamedQueriesNamedQueries({ //in Mitarbeiter ({ //in Mitarbeiter ({ //in Mitarbeiter ({ //in Mitarbeiter (@(@(@(@NamedQueryNamedQueryNamedQueryNamedQuery((((namenamenamename="="="="Mitarbeiter.primaryKeyMitarbeiter.primaryKeyMitarbeiter.primaryKeyMitarbeiter.primaryKey",",",",

queryqueryqueryquery="SELECT m FROM Mitarbeiter m WHERE ="SELECT m FROM Mitarbeiter m WHERE ="SELECT m FROM Mitarbeiter m WHERE ="SELECT m FROM Mitarbeiter m WHERE m.minrm.minrm.minrm.minr= := := := :minrminrminrminr"),"),"),"),@@@@NamedQueryNamedQueryNamedQueryNamedQuery((((namenamenamename="="="="Mitarbeiter.mitFaehigkeitMitarbeiter.mitFaehigkeitMitarbeiter.mitFaehigkeitMitarbeiter.mitFaehigkeit",",",",

queryqueryqueryquery="SELECT m FROM Rolle r JOIN ="SELECT m FROM Rolle r JOIN ="SELECT m FROM Rolle r JOIN ="SELECT m FROM Rolle r JOIN r.mitarbeiterr.mitarbeiterr.mitarbeiterr.mitarbeiter m"m"m"m"+" WHERE r.name = :+" WHERE r.name = :+" WHERE r.name = :+" WHERE r.name = :namenamenamename")")")")

})})})})

// z. B. in Main mit lokalen Variablen // z. B. in Main mit lokalen Variablen // z. B. in Main mit lokalen Variablen // z. B. in Main mit lokalen Variablen minrminrminrminr und und und und faehigkeitfaehigkeitfaehigkeitfaehigkeitMitarbeiter m= Mitarbeiter m= Mitarbeiter m= Mitarbeiter m= emememem

....createNamedQuerycreateNamedQuerycreateNamedQuerycreateNamedQuery("("("("Mitarbeiter.primaryKeyMitarbeiter.primaryKeyMitarbeiter.primaryKeyMitarbeiter.primaryKey"""",,,,Mitarbeiter.classMitarbeiter.classMitarbeiter.classMitarbeiter.class))))

....setParametersetParametersetParametersetParameter("("("("minrminrminrminr", ", ", ", minrminrminrminr))))

....getSingleResultgetSingleResultgetSingleResultgetSingleResult();();();();

forforforfor( Mitarbeiter ( Mitarbeiter ( Mitarbeiter ( Mitarbeiter m:em // m:em // m:em // m:em // EclipseLinkEclipseLinkEclipseLinkEclipseLink Object m:emObject m:emObject m:emObject m:em....createNamedQuerycreateNamedQuerycreateNamedQuerycreateNamedQuery("("("("Mitarbeiter.mitFaehigkeitMitarbeiter.mitFaehigkeitMitarbeiter.mitFaehigkeitMitarbeiter.mitFaehigkeit""""

,,,,Mitarbeiter.classMitarbeiter.classMitarbeiter.classMitarbeiter.class))))....setParametersetParametersetParametersetParameter("("("("namenamenamename", ", ", ", faehigkeitfaehigkeitfaehigkeitfaehigkeit))))....getResultListgetResultListgetResultListgetResultList())())())())

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println(m);(m);(m);(m);

Page 83: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

223Komponentenbasierte Software-Entwicklung

Flexiblere Anfragenkonstruktion (Ausblick)

public void ooartigeAnfragekonstruktion(){public void ooartigeAnfragekonstruktion(){public void ooartigeAnfragekonstruktion(){public void ooartigeAnfragekonstruktion(){

CriteriaBuilder qB = em.getCriteriaBuilder();CriteriaBuilder qB = em.getCriteriaBuilder();CriteriaBuilder qB = em.getCriteriaBuilder();CriteriaBuilder qB = em.getCriteriaBuilder();

CriteriaQuery<Mitarbeiter> cQ =CriteriaQuery<Mitarbeiter> cQ =CriteriaQuery<Mitarbeiter> cQ =CriteriaQuery<Mitarbeiter> cQ =

qB.createQuery(Mitarbeiter.class);qB.createQuery(Mitarbeiter.class);qB.createQuery(Mitarbeiter.class);qB.createQuery(Mitarbeiter.class);

Root<Mitarbeiter> mAlias= cQ.from(Mitarbeiter.class);Root<Mitarbeiter> mAlias= cQ.from(Mitarbeiter.class);Root<Mitarbeiter> mAlias= cQ.from(Mitarbeiter.class);Root<Mitarbeiter> mAlias= cQ.from(Mitarbeiter.class);

cQ.where(qB.notEqual(mAlias.get("name"), "Urs"));cQ.where(qB.notEqual(mAlias.get("name"), "Urs"));cQ.where(qB.notEqual(mAlias.get("name"), "Urs"));cQ.where(qB.notEqual(mAlias.get("name"), "Urs"));

TypedQuery<Mitarbeiter> tq=em.createQuery(cQ);TypedQuery<Mitarbeiter> tq=em.createQuery(cQ);TypedQuery<Mitarbeiter> tq=em.createQuery(cQ);TypedQuery<Mitarbeiter> tq=em.createQuery(cQ);

for(Mitarbeiter m:tq.getResultList())for(Mitarbeiter m:tq.getResultList())for(Mitarbeiter m:tq.getResultList())for(Mitarbeiter m:tq.getResultList())

System.out.println(m.getName());System.out.println(m.getName());System.out.println(m.getName());System.out.println(m.getName());

}}}}

IvanIvanIvanIvanFatmaFatmaFatmaFatmaHeinzHeinzHeinzHeinz

Page 84: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

224Komponentenbasierte Software-Entwicklung

Vererbung – eine Tabelle (1/3)

@Entity@Entity@Entity@Entitypublic class Produkt implements Serializable {public class Produkt implements Serializable {public class Produkt implements Serializable {public class Produkt implements Serializable {@Id @GeneratedValue private int prnr;@Id @GeneratedValue private int prnr;@Id @GeneratedValue private int prnr;@Id @GeneratedValue private int prnr;private String name;private String name;private String name;private String name;private int lagermenge;private int lagermenge;private int lagermenge;private int lagermenge;private float preis;private float preis;private float preis;private float preis;@Version private int version; ...}@Version private int version; ...}@Version private int version; ...}@Version private int version; ...}

@Entity@Entity@Entity@Entitypublic class Lebensmittel extends Produkt implements public class Lebensmittel extends Produkt implements public class Lebensmittel extends Produkt implements public class Lebensmittel extends Produkt implements

Serializable{Serializable{Serializable{Serializable{@Temporal(javax.persistence.TemporalType.DATE)@Temporal(javax.persistence.TemporalType.DATE)@Temporal(javax.persistence.TemporalType.DATE)@Temporal(javax.persistence.TemporalType.DATE)private Date verfallsdatum; ...}private Date verfallsdatum; ...}private Date verfallsdatum; ...}private Date verfallsdatum; ...}

@Entity@Entity@Entity@Entitypublic class Buch extends Produkt{ ...}public class Buch extends Produkt{ ...}public class Buch extends Produkt{ ...}public class Buch extends Produkt{ ...}

Page 85: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

225Komponentenbasierte Software-Entwicklung

Vererbung – eine Tabelle (2/3)

public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) {

EntityManagerFactory eMF =Persistence.EntityManagerFactory eMF =Persistence.EntityManagerFactory eMF =Persistence.EntityManagerFactory eMF =Persistence.

createEntityManagerFactory("JPAVererbungPU");createEntityManagerFactory("JPAVererbungPU");createEntityManagerFactory("JPAVererbungPU");createEntityManagerFactory("JPAVererbungPU");

EntityManager em=eMF.createEntityManager();EntityManager em=eMF.createEntityManager();EntityManager em=eMF.createEntityManager();EntityManager em=eMF.createEntityManager();

em.getTransaction().begin();em.getTransaction().begin();em.getTransaction().begin();em.getTransaction().begin();

em.persist(new Buch("JPA", 2, 39.99f));em.persist(new Buch("JPA", 2, 39.99f));em.persist(new Buch("JPA", 2, 39.99f));em.persist(new Buch("JPA", 2, 39.99f));

em.persist(new Produkt("Maus", 4, 7.99f));em.persist(new Produkt("Maus", 4, 7.99f));em.persist(new Produkt("Maus", 4, 7.99f));em.persist(new Produkt("Maus", 4, 7.99f));

em.persist(new Lebensmittel("Tofu", 7, 0.69f,new Date()));em.persist(new Lebensmittel("Tofu", 7, 0.69f,new Date()));em.persist(new Lebensmittel("Tofu", 7, 0.69f,new Date()));em.persist(new Lebensmittel("Tofu", 7, 0.69f,new Date()));

em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();em.getTransaction().commit();

for(Produkt p:(List<Produkt>)em.for(Produkt p:(List<Produkt>)em.for(Produkt p:(List<Produkt>)em.for(Produkt p:(List<Produkt>)em.

createQuery("SELECT p FROM Produkt p").getResultList())createQuery("SELECT p FROM Produkt p").getResultList())createQuery("SELECT p FROM Produkt p").getResultList())createQuery("SELECT p FROM Produkt p").getResultList())

System.out.println(p);System.out.println(p);System.out.println(p);System.out.println(p);

}}}}1:JPA Menge:2 Preis:39.99 Buch1:JPA Menge:2 Preis:39.99 Buch1:JPA Menge:2 Preis:39.99 Buch1:JPA Menge:2 Preis:39.99 Buch2:Maus Menge:4 Preis:7.992:Maus Menge:4 Preis:7.992:Maus Menge:4 Preis:7.992:Maus Menge:4 Preis:7.993:Tofu Menge:7 Preis:0.69 Verfall:Thu Oct 15 16:22:14 CEST 20093:Tofu Menge:7 Preis:0.69 Verfall:Thu Oct 15 16:22:14 CEST 20093:Tofu Menge:7 Preis:0.69 Verfall:Thu Oct 15 16:22:14 CEST 20093:Tofu Menge:7 Preis:0.69 Verfall:Thu Oct 15 16:22:14 CEST 2009

Page 86: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

226Komponentenbasierte Software-Entwicklung

Vererbung – eine Tabelle (3/3)

SELECT * FROM ProduktSELECT * FROM ProduktSELECT * FROM ProduktSELECT * FROM Produkt

• Abbildung in eine Tabelle ist Default-Einstellung

• Ansatz meist am performantesten

• (float ungeeignet für Geldbeträge)

Page 87: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

227Komponentenbasierte Software-Entwicklung

Vererbung – getrennte verknüpfte Tabellen

@Entity@Entity@Entity@Entity

@@@@InheritanceInheritanceInheritanceInheritance((((strategystrategystrategystrategy====InheritanceType.JOINEDInheritanceType.JOINEDInheritanceType.JOINEDInheritanceType.JOINED))))

publicpublicpublicpublic classclassclassclass Produkt Produkt Produkt Produkt implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable { { { { ...}...}...}...}

SELECT * FROM ProduktSELECT * FROM ProduktSELECT * FROM ProduktSELECT * FROM Produkt

SELECT * FROM LebensmittelSELECT * FROM LebensmittelSELECT * FROM LebensmittelSELECT * FROM Lebensmittel

SELECT * FROM BuchSELECT * FROM BuchSELECT * FROM BuchSELECT * FROM Buch

Page 88: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

228Komponentenbasierte Software-Entwicklung

Vererbung – getrennte Tabellen

@Entity@Entity@Entity@Entity

@@@@InheritanceInheritanceInheritanceInheritance((((strategystrategystrategystrategy====InheritanceType.TABLE_PER_CLASSInheritanceType.TABLE_PER_CLASSInheritanceType.TABLE_PER_CLASSInheritanceType.TABLE_PER_CLASS))))

publicpublicpublicpublic classclassclassclass Produkt Produkt Produkt Produkt implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable { { { { ...}...}...}...}

SELECT * FROM ProduktSELECT * FROM ProduktSELECT * FROM ProduktSELECT * FROM Produkt

SELECT * FROM LebensmittelSELECT * FROM LebensmittelSELECT * FROM LebensmittelSELECT * FROM Lebensmittel

SELECT * FROM BuchSELECT * FROM BuchSELECT * FROM BuchSELECT * FROM Buch

Page 89: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

229Komponentenbasierte Software-Entwicklung

Software-Architektur

• sinnvoll: Datenzugriff kapseln

• typisch mehrere DAO-Klassen

• entsteht Datenzugriffs-komponente

Page 90: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

230Komponentenbasierte Software-Entwicklung

Einbindung von Bean-Validation

• Annotationen wie @Column ermöglichen bereits Angabe bestimmter Randbedingungen

• klarerer Ansatz: Trennung von Beschreibung des Objektgraphen (wer mit wem) von Validierung

• Bean-Validation kann zusammen mit JPA genutzt werden; Anwesenheit von Validatoren wird von EntityManagern genutzt

• Ansatz: Wenn Daten in DB persistiert werden sollen, werden alle Validierungsregeln geprüft (nicht eher); bei Fehler wird Exception geworfen

• Zukunft: Standards werden noch enger verknüpft

• Beispiel: externe Programmierernamen beginnen mit „X“, müssen vorgegebene Sprachen können

Page 91: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

231Komponentenbasierte Software-Entwicklung

Beispiel: JPA mit Bean-Validation (1/5)

@Entity @Entity @Entity @Entity @@@@MrXProgrammerMrXProgrammerMrXProgrammerMrXProgrammer(sprachen={"(sprachen={"(sprachen={"(sprachen={"Java","EJava","EJava","EJava","E"},"},"},"},messagemessagemessagemessage="aktuelle Sprachen")="aktuelle Sprachen")="aktuelle Sprachen")="aktuelle Sprachen")publicpublicpublicpublic classclassclassclass Mitarbeiter Mitarbeiter Mitarbeiter Mitarbeiter implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

@@@@IdIdIdId @@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValue((((strategystrategystrategystrategy = = = = GenerationType.AUTOGenerationType.AUTOGenerationType.AUTOGenerationType.AUTO))))private private private private intintintint minrminrminrminr;;;;@@@@NotNullNotNullNotNullNotNull @Size(min=2, @Size(min=2, @Size(min=2, @Size(min=2, messagemessagemessagemessage="echter Nachname")="echter Nachname")="echter Nachname")="echter Nachname")private String private String private String private String namenamenamename;;;;@@@@OneToManyOneToManyOneToManyOneToMany((((mappedBymappedBymappedBymappedBy = "= "= "= "bearbeiterbearbeiterbearbeiterbearbeiter",",",",

cascadecascadecascadecascade = {= {= {= {CascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSIST, , , , CascadeType.MERGECascadeType.MERGECascadeType.MERGECascadeType.MERGE})})})})@Basic(@Basic(@Basic(@Basic(fetchfetchfetchfetch = = = = FetchType.EAGERFetchType.EAGERFetchType.EAGERFetchType.EAGER))))@Size(@Size(@Size(@Size(maxmaxmaxmax=3, =3, =3, =3, messagemessagemessagemessage="="="="maxmaxmaxmax 3 3 3 3 AuftraegeAuftraegeAuftraegeAuftraege")")")")private Set<Projektauftrag> private Set<Projektauftrag> private Set<Projektauftrag> private Set<Projektauftrag> auftraegeauftraegeauftraegeauftraege = = = = newnewnewnew HashSetHashSetHashSetHashSet<>();<>();<>();<>();@@@@ManyToManyManyToManyManyToManyManyToMany((((mappedBymappedBymappedBymappedBy = "= "= "= "mitarbeitermitarbeitermitarbeitermitarbeiter",",",",

cascadecascadecascadecascade = {= {= {= {CascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSISTCascadeType.PERSIST, , , , CascadeType.MERGECascadeType.MERGECascadeType.MERGECascadeType.MERGE})})})})@Basic(@Basic(@Basic(@Basic(fetchfetchfetchfetch = = = = FetchType.EAGERFetchType.EAGERFetchType.EAGERFetchType.EAGER))))@Size(@Size(@Size(@Size(maxmaxmaxmax=2, =2, =2, =2, messagemessagemessagemessage="="="="maxmaxmaxmax 2 Rollen")2 Rollen")2 Rollen")2 Rollen")private List<Rolle> rollen = private List<Rolle> rollen = private List<Rolle> rollen = private List<Rolle> rollen = newnewnewnew ArrayListArrayListArrayListArrayList<>();<>();<>();<>();// ...// ...// ...// ...

Page 92: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

232Komponentenbasierte Software-Entwicklung

Beispiel: JPA mit Bean-Validation (2/5)

@Target({ElementType.TYPE})@Target({ElementType.TYPE})@Target({ElementType.TYPE})@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)@Retention(RetentionPolicy.RUNTIME)@Retention(RetentionPolicy.RUNTIME)@Retention(RetentionPolicy.RUNTIME)

@Constraint(validatedBy = MrXValidator.class)@Constraint(validatedBy = MrXValidator.class)@Constraint(validatedBy = MrXValidator.class)@Constraint(validatedBy = MrXValidator.class)

@Documented@Documented@Documented@Documented

public @interface MrXProgrammer {public @interface MrXProgrammer {public @interface MrXProgrammer {public @interface MrXProgrammer {

String message() default "Moduleintrag kaputt";String message() default "Moduleintrag kaputt";String message() default "Moduleintrag kaputt";String message() default "Moduleintrag kaputt";

Class<?>[] groups() default {};Class<?>[] groups() default {};Class<?>[] groups() default {};Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};Class<? extends Payload>[] payload() default {};Class<? extends Payload>[] payload() default {};Class<? extends Payload>[] payload() default {};

String[] sprachen() default {};String[] sprachen() default {};String[] sprachen() default {};String[] sprachen() default {};

}}}}

Page 93: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

233Komponentenbasierte Software-Entwicklung

Beispiel: JPA mit Bean-Validation (3/5)

public class MrXValidator implementspublic class MrXValidator implementspublic class MrXValidator implementspublic class MrXValidator implementsConstraintValidator<MrXProgrammer, Mitarbeiter> {ConstraintValidator<MrXProgrammer, Mitarbeiter> {ConstraintValidator<MrXProgrammer, Mitarbeiter> {ConstraintValidator<MrXProgrammer, Mitarbeiter> {

private String[] muss;private String[] muss;private String[] muss;private String[] muss;

public void initialize(MrXProgrammer a) {public void initialize(MrXProgrammer a) {public void initialize(MrXProgrammer a) {public void initialize(MrXProgrammer a) {muss = a.sprachen();muss = a.sprachen();muss = a.sprachen();muss = a.sprachen();

}}}}

public boolean isValid(Mitarbeiter t, public boolean isValid(Mitarbeiter t, public boolean isValid(Mitarbeiter t, public boolean isValid(Mitarbeiter t, ConstraintValidatorContext cvc) {ConstraintValidatorContext cvc) {ConstraintValidatorContext cvc) {ConstraintValidatorContext cvc) {

System.out.println("Pruefe fuer "+t.getName());System.out.println("Pruefe fuer "+t.getName());System.out.println("Pruefe fuer "+t.getName());System.out.println("Pruefe fuer "+t.getName());if(!t.getName().startsWith("X"))if(!t.getName().startsWith("X"))if(!t.getName().startsWith("X"))if(!t.getName().startsWith("X"))return true;return true;return true;return true;

List<Rolle> rollen = t.getRollen();List<Rolle> rollen = t.getRollen();List<Rolle> rollen = t.getRollen();List<Rolle> rollen = t.getRollen();for (Rolle r : rollen)for (Rolle r : rollen)for (Rolle r : rollen)for (Rolle r : rollen)for (String s : muss)for (String s : muss)for (String s : muss)for (String s : muss)if (r.getName().equals(s))if (r.getName().equals(s))if (r.getName().equals(s))if (r.getName().equals(s))return true;return true;return true;return true;

return false;return false;return false;return false;}}}}

}}}}

Page 94: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

234Komponentenbasierte Software-Entwicklung

Beispiel: JPA mit Bean-Validation (4/5)publicpublicpublicpublic void void void void beispieldatenbeispieldatenbeispieldatenbeispieldaten(){(){(){(){

Mitarbeiter m1 = Mitarbeiter m1 = Mitarbeiter m1 = Mitarbeiter m1 = newnewnewnew Mitarbeiter("Mitarbeiter("Mitarbeiter("Mitarbeiter("XUrsXUrsXUrsXUrs");");");");Rolle[] r= { Rolle[] r= { Rolle[] r= { Rolle[] r= { newnewnewnew Rolle("Java", 60),Rolle("Java", 60),Rolle("Java", 60),Rolle("Java", 60),newnewnewnew Rolle("C", 50)};Rolle("C", 50)};Rolle("C", 50)};Rolle("C", 50)};forforforfor((((intintintint i=0;i<i=0;i<i=0;i<i=0;i<r.length;ir.length;ir.length;ir.length;i++) m1.rolleHinzu(r[i]);++) m1.rolleHinzu(r[i]);++) m1.rolleHinzu(r[i]);++) m1.rolleHinzu(r[i]);System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println(m1);(m1);(m1);(m1);trytrytrytry {{{{em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();em.persistem.persistem.persistem.persist(m1);(m1);(m1);(m1);em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();

} catch (} catch (} catch (} catch (ConstraintViolationExceptionConstraintViolationExceptionConstraintViolationExceptionConstraintViolationException e) {e) {e) {e) {System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((e.getMessagee.getMessagee.getMessagee.getMessage());());());());forforforfor((((ConstraintViolationConstraintViolationConstraintViolationConstraintViolation c:e.getConstraintViolations())c:e.getConstraintViolations())c:e.getConstraintViolations())c:e.getConstraintViolations())

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((c.getMessagec.getMessagec.getMessagec.getMessage());());());());ifififif ((((em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().isActiveisActiveisActiveisActive())())())())em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().rollbackrollbackrollbackrollback();();();();

}}}}}}}} 0: XUrs Auftraege=[ ]0: XUrs Auftraege=[ ]0: XUrs Auftraege=[ ]0: XUrs Auftraege=[ ]

Rollen=[ Java C ]Rollen=[ Java C ]Rollen=[ Java C ]Rollen=[ Java C ]Pruefe fuer XUrsPruefe fuer XUrsPruefe fuer XUrsPruefe fuer XUrs

Page 95: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

235Komponentenbasierte Software-Entwicklung

Beispiel: JPA mit Bean-Validation (5/5)

publicpublicpublicpublic void void void void beispieldatenbeispieldatenbeispieldatenbeispieldaten(){(){(){(){Mitarbeiter m1 = Mitarbeiter m1 = Mitarbeiter m1 = Mitarbeiter m1 = newnewnewnew Mitarbeiter("X");Mitarbeiter("X");Mitarbeiter("X");Mitarbeiter("X");Rolle[] r= { Rolle[] r= { Rolle[] r= { Rolle[] r= { newnewnewnew Rolle("C++", 60),Rolle("C++", 60),Rolle("C++", 60),Rolle("C++", 60),newnewnewnew Rolle("C", 50),Rolle("C", 50),Rolle("C", 50),Rolle("C", 50),

newnewnewnew Rolle("Cobol", 70)};Rolle("Cobol", 70)};Rolle("Cobol", 70)};Rolle("Cobol", 70)};forforforfor((((intintintint i=0;i<i=0;i<i=0;i<i=0;i<r.length;ir.length;ir.length;ir.length;i++) m1.rolleHinzu(r[i]);++) m1.rolleHinzu(r[i]);++) m1.rolleHinzu(r[i]);++) m1.rolleHinzu(r[i]);System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println(m1);(m1);(m1);(m1);trytrytrytry {{{{em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().beginbeginbeginbegin();();();();em.persistem.persistem.persistem.persist(m1);(m1);(m1);(m1);em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().commitcommitcommitcommit();();();();

} catch (} catch (} catch (} catch (ConstraintViolationExceptionConstraintViolationExceptionConstraintViolationExceptionConstraintViolationException e) {e) {e) {e) {forforforfor((((ConstraintViolationConstraintViolationConstraintViolationConstraintViolation c:e.getConstraintViolations())c:e.getConstraintViolations())c:e.getConstraintViolations())c:e.getConstraintViolations())System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((c.getMessagec.getMessagec.getMessagec.getMessage());());());());

ifififif ((((em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().isActiveisActiveisActiveisActive())())())())em.getTransactionem.getTransactionem.getTransactionem.getTransaction().().().().rollbackrollbackrollbackrollback();();();();

}}}}}}}}

0: X Auftraege=[ ]0: X Auftraege=[ ]0: X Auftraege=[ ]0: X Auftraege=[ ]Rollen=[ C++ C Cobol ]Rollen=[ C++ C Cobol ]Rollen=[ C++ C Cobol ]Rollen=[ C++ C Cobol ]

Pruefe fuer XPruefe fuer XPruefe fuer XPruefe fuer Xechter Nachnameechter Nachnameechter Nachnameechter Nachnameaktuelle Sprachenaktuelle Sprachenaktuelle Sprachenaktuelle Sprachenmax 2 Rollenmax 2 Rollenmax 2 Rollenmax 2 Rollen

TODO: Exception tritt erst bei DB-Nutzungauf, sinnvoll früher

Page 96: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

236

Technischer Hinweis

• Beispiele zeigen, dass die Version 4.2 und 4.3 der Bean Validation nicht mit EclipseLink 2.3.2 zusammenarbeiten

• Lösung: Bean Validation 5.0.0.Alpha1 (wie vorher)

Komponentenbasierte Software-Entwicklung

Page 97: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

237Komponentenbasierte Software-Entwicklung

Interessante weitere Features in JPA

• in Anfrage-Sprache– Funktionen auf Datentypen z. B.

SUBSTRING(String,Start,Ende)– UPDATE und DELETE in Querys

• immer vor/nach Persistierung ausgeführte Methoden• Compound Primary Keys , zusammengesetzte Schlüssel über

Hilfsklassen nutzbar• Verschiedene Sperrvarianten

@Lob @Column(name="PIC")@Lob @Column(name="PIC")@Lob @Column(name="PIC")@Lob @Column(name="PIC")private byte[] picture;private byte[] picture;private byte[] picture;private byte[] picture;

@ManyToMany@ManyToMany@ManyToMany@ManyToMany@JoinTable(name="PROJEKTROLLEN",@JoinTable(name="PROJEKTROLLEN",@JoinTable(name="PROJEKTROLLEN",@JoinTable(name="PROJEKTROLLEN",joinColumns=@JoinColumn(name=„ROLLEN_ID"),joinColumns=@JoinColumn(name=„ROLLEN_ID"),joinColumns=@JoinColumn(name=„ROLLEN_ID"),joinColumns=@JoinColumn(name=„ROLLEN_ID"),inverseJoinColumns=@JoinColumn(name="PROJ_ID"))inverseJoinColumns=@JoinColumn(name="PROJ_ID"))inverseJoinColumns=@JoinColumn(name="PROJ_ID"))inverseJoinColumns=@JoinColumn(name="PROJ_ID"))

Page 98: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

238

• Datenbank als zentrale Kommunikationsplattform

• Ansatz 1: alle Komponenten kennen Entitäten-Modell

• Ansatz 2: Datenzugriffsschicht kapselt Datenbank

Komponentenbasierte Software-Entwicklung

Erinnerung: Eine Komponentenarchitektur-Variante

Page 99: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

239

Ansatz 1: Alle kennen Entitäten-Modell (1/2)

• Datenbank als zentrale Kommunikationsplattform

• Entitäten sind bekannt, jede Komponente kann zugreifen

• Benötigt Komponente weitere Eigenschaft einer Entität wird keine Spalte sondern Tabelle ergänzt (auch 1:1, 1:C, nutzt Primärschlüssel)

• Sehr einfache Architektur

• Sehr gut Komponenten an- und ausschaltbar

• Keine Benachrichtigung bei Änderungen (sichtbar beim nächsten Lesen)

• Stark eingeschränkte Wiederverwendbarkeit

• Keine echte Informationskapselung

• Wartbarkeit nimmt mit Systemgröße enorm ab

Komponentenbasierte Software-Entwicklung

Page 100: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

240

Ansatz 1: Alle kennen Entitäten-Modell (2/2)

• Beispiel: Komponenten Produktverwaltung, Bestellsystem (sieht neue Produkte und Änderungen bei nächsten Aufruf)

Komponentenbasierte Software-Entwicklung

Page 101: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

241

Ansatz 2: Kapselung mit Datenzugriffsschicht (1/2)

• Kein direkter Zugriff auf Tabellen

• Ermöglicht auch Benachrichtigungen (Observer)

• Zerlegung in wiederverwendbare Komponenten

• Unterschiedliche Varianten von Kommunikationen möglich

– Nutzung einer zentralen Zugriffskomponente, die DB kapselt und Observer verwaltet

– Nur Data Access Objects können miteinander reden

– Komponentenschnittstellen unabhängig von der DB

– Selbst gemeinsame Datenbank ist optional

Komponentenbasierte Software-Entwicklung

Page 102: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

242

Ansatz 2: Kapselung mit Datenzugriffsschicht (2/2)

Komponentenbasierte Software-Entwicklung

Page 103: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

243

Überwachungsmethoden (1/3)

@@@@EntityEntityEntityEntity

publicpublicpublicpublic classclassclassclass Mitarbeiter Mitarbeiter Mitarbeiter Mitarbeiter {{{{

@@@@IdIdIdId @@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValue((((strategystrategystrategystrategy====GenerationType.AUTOGenerationType.AUTOGenerationType.AUTOGenerationType.AUTO))))

private private private private intintintint minrminrminrminr;;;;

private private private private String String String String namenamenamename;;;;

private void p(String s){private void p(String s){private void p(String s){private void p(String s){System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println(s);}(s);}(s);}(s);}

@@@@PrePersistPrePersistPrePersistPrePersist publicpublicpublicpublic voidvoidvoidvoid prePersitprePersitprePersitprePersit() () () () {p("{p("{p("{p("prePersistprePersistprePersistprePersist");}");}");}");}

@@@@PostPersistPostPersistPostPersistPostPersist publicpublicpublicpublic voidvoidvoidvoid postPersistpostPersistpostPersistpostPersist() () () () {p("{p("{p("{p("postPersistpostPersistpostPersistpostPersist");}");}");}");}

@@@@PreRemovePreRemovePreRemovePreRemove publicpublicpublicpublic voidvoidvoidvoid preRemovepreRemovepreRemovepreRemove() () () () {p("{p("{p("{p("preRemovepreRemovepreRemovepreRemove");}");}");}");}

@@@@PostRemovePostRemovePostRemovePostRemove publicpublicpublicpublic voidvoidvoidvoid postRemovepostRemovepostRemovepostRemove() () () () {p("{p("{p("{p("postRemovepostRemovepostRemovepostRemove");}");}");}");}

@@@@PreUpdatePreUpdatePreUpdatePreUpdate publicpublicpublicpublic voidvoidvoidvoid preUpdatepreUpdatepreUpdatepreUpdate() () () () {p("{p("{p("{p("preUpdatepreUpdatepreUpdatepreUpdate");}");}");}");}

@@@@PostUpdatePostUpdatePostUpdatePostUpdate publicpublicpublicpublic voidvoidvoidvoid postUpdatepostUpdatepostUpdatepostUpdate() () () () {p("{p("{p("{p("postUpdatepostUpdatepostUpdatepostUpdate");}");}");}");}

@@@@PostLoadPostLoadPostLoadPostLoad publicpublicpublicpublic voidvoidvoidvoid postLoadpostLoadpostLoadpostLoad() () () () {p("{p("{p("{p("postLoadpostLoadpostLoadpostLoad");}");}");}");}

// Hinweis: Rollback bei einer // Hinweis: Rollback bei einer // Hinweis: Rollback bei einer // Hinweis: Rollback bei einer RuntimeRuntimeRuntimeRuntime ExceptionExceptionExceptionException

............Komponentenbasierte Software-

Entwicklung

Page 104: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

244

Überwachungsmethoden (2/3)

publicpublicpublicpublic staticstaticstaticstatic voidvoidvoidvoid mainmainmainmain(String[] (String[] (String[] (String[] argsargsargsargs) {) {) {) {EntityManagerFactoryEntityManagerFactoryEntityManagerFactoryEntityManagerFactory emfemfemfemf = = = = PersistencePersistencePersistencePersistence

....createEntityManagerFactorycreateEntityManagerFactorycreateEntityManagerFactorycreateEntityManagerFactory("("("("PrePostPUPrePostPUPrePostPUPrePostPU");");");");EntityManagerEntityManagerEntityManagerEntityManager emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager();();();();Mitarbeiter Mitarbeiter Mitarbeiter Mitarbeiter m = m = m = m = newnewnewnew Mitarbeiter("Olga");Mitarbeiter("Olga");Mitarbeiter("Olga");Mitarbeiter("Olga");Mitarbeiter Mitarbeiter Mitarbeiter Mitarbeiter m2 = m2 = m2 = m2 = newnewnewnew Mitarbeiter("Otto");Mitarbeiter("Otto");Mitarbeiter("Otto");Mitarbeiter("Otto");EntityTransactionEntityTransactionEntityTransactionEntityTransaction tatatata = = = = em.getTransactionem.getTransactionem.getTransactionem.getTransaction();();();();ta.beginta.beginta.beginta.begin();();();();em.persistem.persistem.persistem.persist(m(m(m(m););););em.persistem.persistem.persistem.persist(m2(m2(m2(m2););););em.persistem.persistem.persistem.persist((((newnewnewnew Mitarbeiter("Urs"));Mitarbeiter("Urs"));Mitarbeiter("Urs"));Mitarbeiter("Urs"));ta.committa.committa.committa.commit();();();();ta.beginta.beginta.beginta.begin();();();();Mitarbeiter Mitarbeiter Mitarbeiter Mitarbeiter mm = mm = mm = mm = em.findem.findem.findem.find((((Mitarbeiter.classMitarbeiter.classMitarbeiter.classMitarbeiter.class, , , , m.getMinrm.getMinrm.getMinrm.getMinr());());());());mm.setNamemm.setNamemm.setNamemm.setName("Anna");("Anna");("Anna");("Anna");em.persistem.persistem.persistem.persist(mm(mm(mm(mm););););ta.committa.committa.committa.commit();();();();

Komponentenbasierte Software-Entwicklung

prePersistprePersistprePersistprePersistprePersistprePersistprePersistprePersistprePersistprePersistprePersistprePersistpostPersistpostPersistpostPersistpostPersistpostPersistpostPersistpostPersistpostPersistpostPersistpostPersistpostPersistpostPersistpreUpdatepreUpdatepreUpdatepreUpdatepostUpdatepostUpdatepostUpdatepostUpdate

Page 105: 4. Java Persistence API (JPA) - home.edvsz.hs-osnabrueck.dehome.edvsz.hs-osnabrueck.de/skleuker/WS12_KbSE/WS1213KbSE_Teil4.pdf · Prof. Dr. Stephan Kleuker Komponentenbasierte Software-

Prof. Dr. Stephan Kleuker

245

Überwachungsmethoden (3/3)

ta.beginta.beginta.beginta.begin();();();();

em.removeem.removeem.removeem.remove(m(m(m(m););););

ta.committa.committa.committa.commit();();();();

em.closeem.closeem.closeem.close(); // notwendig für neuen Kontext(); // notwendig für neuen Kontext(); // notwendig für neuen Kontext(); // notwendig für neuen Kontext

emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager();();();();

forforforfor (Mitarbeiter m3 : (Mitarbeiter m3 : (Mitarbeiter m3 : (Mitarbeiter m3 : em.createQueryem.createQueryem.createQueryem.createQuery((((

""""SELECT m FROM Mitarbeiter SELECT m FROM Mitarbeiter SELECT m FROM Mitarbeiter SELECT m FROM Mitarbeiter m"m"m"m"

, , , , Mitarbeiter.classMitarbeiter.classMitarbeiter.classMitarbeiter.class))))

....getResultListgetResultListgetResultListgetResultList()) ()) ()) ())

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println(m3.getMinr(m3.getMinr(m3.getMinr(m3.getMinr() () () ()

+ + + + ": " + m3.getName": " + m3.getName": " + m3.getName": " + m3.getName());());());());

em.closeem.closeem.closeem.close();();();();

emf.closeemf.closeemf.closeemf.close();();();();

}}}}

Komponentenbasierte Software-Entwicklung

preRemovepreRemovepreRemovepreRemovepostRemovepostRemovepostRemovepostRemovepostLoadpostLoadpostLoadpostLoadpostLoadpostLoadpostLoadpostLoad2: Otto2: Otto2: Otto2: Otto3: 3: 3: 3: UrsUrsUrsUrs