JPA 2.0 Java-Framework Autor Stephan Metzler Version 4.0 © 2010 JPA 2.0 >> Java Framework >> 2. Tag 1. Tag MileStones Seite A Java Community 5 B Verteilte Systeme 18 C Java EE 21 D Testen 29 E JPA 38 F Transaktionen 109 G Idioms 124 H Trends 134 I 138 Referenzen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 2 >> total: 140 Seiten JPA 2.0 >> Java Framework >> A Java Community Lerninhalte Technologien Entwurfsmuster Entwicklungtools Paradigmen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 3 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform 1 Java Plattform Die Java Plattform ist in drei Editionen aufgeteilt JME JSE JEE Micro Edition Standard Edition Enterprise Edition - Umgebung - robust - flexible - Ziel-Applikationen - embedded devices - Mobil-Telefone PDAs - Inhalt - VM - Kommunikationsprozesse - Inhalt - JRE - - - Definition - Standard (Framework) APIs VM JDK - JRE - Compiler - Debugger - - Inhalt - Dienstleistungen - Basis für JEE Multi-User Multi-Tier Enterprise Appl. Zugriff transparente Lösungen - Verhalten OOA / OOD hilfreiche und wichtige Neuerungen im Java-Standard (seit JDK 1.5) - Annotations ►Metadaten im Source - Generics ►parametrischer Polymorphie Entwurfmuster - Dependency Injection ►Objekte erhalten ihre Abhängigkeiten passiv Paradigma - AOP Aspect Orientiertes Programmieren ►trennt System- von Businesslogik Tools im Umgang mit JEE Technologien - Maven ► Build-Management-Tool der Apache Software Foundation Log4J ► Loggen von Informationen ►Wiederverwendbarkeit JUnit ►Test-Framework Mock ► dynamisches (Dummy-) Test-Objekt © 2010 >> Stephan Metzler >> V 4.0 >> Seite 4 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform 1.1 Annotations wiki Annotation bedeutet "Anmerkung", "Beifügung", "Hinzufügung". In diesem Sinn haben Annotationen bei Stichworten, Stichworten, Begriffsklärungen oder ausführlichen Texten den Charakter Charakter der Erklärung beziehungsweise Ergänzung. In der Softwareentwicklung dienen Annotationen dazu, Metadaten in den Quelltext eines Programms einzubinden. Diese haben keine direkte Auswirkung auf die Übersetzung des Quelltextes, bieten aber zusätzliche Möglichkeiten Möglichkeiten im Vergleich zu einfachen Kommentaren. Kommentaren. Eigenschaften - Metadaten direkt im Sourcecode ►zentral XML- oder Property-Dateien entfallen ► mehrere Dateien sein z.T. umständlich werden von Codegenerierungstools ausgelesen ► Controlle bei der Entwicklung werden zur Laufzeit per Reflection abgefragt ► zur dynamischen Verwendung in Frameworks - Zuordnung zum Sourcecode ersichtlich ► als Entwickler Vorteil Verwendung von Annotations - Annotations werden im Sourcecode vor dem zu markierenden Element eingefügt - @ als Kennzeichnung vorangestellt - Leerzeichen sind erlaubt - Parameter als Name-Wert-Paar in Klammern an den Annotationsnamen angehängt @MyAnnotation(parameter1 = "hallo", parameter2 = "world") - Reihenfolge der Parameter spielt keine Rolle hat die Annotation nur einen Parameter, kann der Name weggelassen werden bei parameterlosen Annotations ist die Angabe der Klammern optional Annotations können sich auf folgende Java-Elemente beziehen: - Packages, Klassen, Interfaces, Enumerations, Methoden, Variablen, Methodenparameter © 2010 >> Stephan Metzler >> V 4.0 >> Seite 5 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Annotations in der Java JSE 5.0 - definiert sieben Annotations - Standard Annotation ►normale Verwendung beim Programmieren - Meta Annotation ►Definition neuer Annotationstypen Standard Annotations - @Deprecated - kennzeichnet Methoden und Klassen, die nicht mehr verwendet werden sollen - @Override - der Compiler stellt sicher, dass die Methode der Basisklasse überschrieben wird - @SuppressWarnings - unterdrückt Compilerwarnungen. Warnungen werden als Parameter angegeben Beispiel @Deprecated / @Override public class HelloWorld { @Deprecated public String sayHello() { return "Hello World"; } @Override public String toString() { return "Hello World"; } } - sayHello() ist veraltet und erzeugt Compilerwarnung - toString() mit @Override stellt sicher, dass toString() aus Object überschrieben wird © 2010 >> Stephan Metzler >> V 4.0 >> Seite 6 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Meta Annotations - @Documented - zur Erzeugung der Dokumentation bei Javadoc - @Inherited - Annotation-Typ wird vererbt, auch rekursiv, falls keine Annotation in der aktuellen Klasse gefunden wird. - @Retention - Definiert wie lange die Annotation verfügbar ist - SOURCE nur bis zur Compilerzeit zur Verfügung - CLASS (DEFAULT) werden in den Class-Dateien abgespeichert, aber nicht von der VM geladen - RUNTIME werden in der Class-Datei abgelegt und von der VM geladen und stehen somit zur Auswertung per Reflection zur Verfügung - @Target - definiert Elemente (Klasse, Methode, Parameter etc.) denen eine Annotation zugeordnet werden kann Beispiel selbst definierter Annotation public enum Datentyp { TEXT, NUMMER, DATUM } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Datenfeld { String bezeichnung() default ""; Datentyp datentyp() default Datentyp.TEXT; } - @Retention(RetentionPolicy.RUNTIME) definiert die Verfügbarkeit - RUNTIME : Auswertung zur Laufzeit - @Target({ElementType.FIELD}) definiert wo die Annotation eingesetzt werden kann - FIELD : für Attribute - @interface definiert das annotierte API Element "Datenfeld" - Parameter : Bezeichnung und Datentyp (sind optional und mit Default-Werten) © 2010 >> Stephan Metzler >> V 4.0 >> Seite 7 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Anwendung: Klasse Person annotiert Attribute als Datenfelder public class Person implements java.io.Serializable { @Datenfeld(bezeichnung = "Nummer", datentyp = Datentyp.NUMMER) private int nr; @Datenfeld(bezeichnung = "Name", datentyp = Datentyp.TEXT) private String name; @Datenfeld private String beschreibung; } Auslesen der Annotationen Person p = new Person(); Field[] fields = p.getClass().getDeclaredFields(); for (Field field : fields) { Datenfeld datenfeld = field.getAnnotation(Datenfeld.class); if (datenfeld != null) { System.out.println("\nannotiertes Attribut: " + field.getName()); if (datenfeld.bezeichnung().length() != 0) { System.out.println("\tBEZ = " + datenfeld.bezeichnung()); } System.out.println("\tTYP = " + datenfeld.datentyp()); } Aufgabe ► selbstdefinierte Annotation - Testen Sie die Annotaion @Datenfeld annotiertes Attribut: nr BEZ = Nummer TYP = NUMMER annotiertes Attribut: name BEZ = Name TYP = TEXT annotiertes Attribut: beschreibung TYP = TEXT © 2010 >> Stephan Metzler >> V 4.0 >> Seite 8 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform 1.2 Generics wiki In der Informatik sind sind Generische Typen Datentypen mit der Möglichkeit zur Angabe von Typparametern. Man spricht auch von parametrischer Polymorphie. Polymorphie. Ein generischer Typ erlaubt es, Datentypen zu erzeugen, die von den zu Grunde liegenden Typen abstrahieren. So würden eine Liste Liste von Zahlen, eine Liste von Zeichen und eine Liste von Datumsangaben im Grunde auf dieselbe Weise programmiert werden. Die Algorithmen zum Einfügen, Suchen und Löschen würden stets gleich ablaufen. Es ist daher wünschenswert, die Implementierung der Liste Liste unabhängig von diesen Typen vorzunehmen Eigenschaften - erlauben die Abstraktion von Typen erlaubt Wiederverwendbarkeit von Funktionalitäten defineren generische Klassen und Methoden, unabhängig von einem konkreten Typ definieren parametrische Polymorphie Generics verbessert die Lesbarkeit und hilft durch die erhöhte Typsicherheit die Zuverlässigkeit des Codes zu erhöhen. normale Collections List v = new Vector(); v.add(new Double(1.0)); Double d = (Double)v.get(0); - Cast auf Double ist notwendig, denn der Rückgabewert von get(...) ist Objekt - erlaubt inkompatible Typen in die Liste einzuführen generische Collections List<Double> v = new Vector<Double>(); v.add(new Double(1.0)); Double d = v.get(0); - v ist eine Liste von (nur) Double - Typ in spitzen Klammern definiert den konkreten Typparameter - Verwendung wird durch Compiler sichergestellt und zur Compilezeit erkannt - Casts entfallen, da Rückgabewert von get(...) nur Double ist - mehrere Typparameter werden durch Komma getrennt (z. B. Hashtable<Long, String>) © 2010 >> Stephan Metzler >> V 4.0 >> Seite 9 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Wildcards und Bounds - unabhängiger Code - Implementierung von Such- oder Sortieralgorithmen - Wildcardzeichen ist ? - Vector<?> steht für einen Vector mit beliebigem Inhalt - Bounds als Angabe von Schranken - extends limitiert auf den angegebenen oder abgeleiteten Typ - super limitiert auf den angegebenen oder vererbten Typ Beispiel parametriesierter Polymorphie Vector<?> v1; Vector<String> v2 = new Vector<String>(); v1 = v2; // nur String List<? extends Number> 100; // Number oder Subtyp List<? super String> 2; // String oder Supertyp generische Typen - Generics sind nicht auf die Verwendung bestehender Klassen beschränkt - eigene generische Typen können definiert werden Definition der generischen Klasse MyGeneric - Enthält zwei Typparameter (K und V) - die Typparameter können wie normale Typen bei der Definition der Klasse verwendet werden public class MyGeneric<K, V> { private K key; private V value; public MyGeneric(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 10 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Aufgabe ► genererische Typen / generische Methoden - Typparameter wie normale Typen bei der Definition der Klasse verwenden @Test public void testMyGeneric() { K key = (K) "test"; V value = (V) (new Integer(123)); MyGeneric<K, V> myGeneric = new MyGeneric<K, V>(key, value); assertEquals(key, myGeneric.getKey()); assertEquals(value, myGeneric.getValue()); } - generische Methoden ► generische Methode sayHello(...) enthält zwei Typparameter public static <E, T> String sayHello(E pre, T post) { return (pre.toString() + " hello " + post.toString()); } @Test public void testSayHello() { assertEquals("generic hello world", sayHello("generic", new StringBuffer("world"))); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 11 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform 1.3 Project Lombok - Code Generator ► http://projectlombok.org/ - umgeht Java Konvetionen für JavaBeans - definieren des Default Konstruktor generieren von getter / setter überschreiben von toString / euqals / hashcode - Plugin für Eclipse ► http://projectlombok.googlecode.com/files/lombok.jar - ausführbare Datei - lombok.jar in den Project ClassPath einbinden import lombok.Data; @Data public class Konto { private String nr; private String name; private Float saldo; } Lombok Annotations Annotation Verwendung generiert getter und setter Methoden der verwendeten Attributen @Getter / @Setter @ToString generiert entsprechende toString Methode @EqualsAndHashCode generiert equals und hashCode Methoden generiert Konstruktorenen @NoArgsConstructor @RequiredArgsConstructor Default Konstruktor ohne Argumente Konstruktoren für final / alle Attrbute @AllArgsConstructor @Data generiert Artefakte für ein Data Objekt @ToString, @EqualsAndHashCode, @Getter für alle Attribute, @Setter für non-final Afftribute, und @RequiredArgsConstructor @Cleanup automatisches Ressourcenmanagment @Synchronized synchronisiert statische und Klassen-Methoden @SneakyThrows übergeht checked exceptions © 2010 >> Stephan Metzler >> V 4.0 >> Seite 12 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform 1.4 Dependency Injection wiki Dependency Injection (DI) ist ein Entwurfsmuster und dient in einem objektorientierten System dazu, die Abhängigkeiten zwischen Komponenten oder Objekten zu minimieren. Dependency Injection ist eine Anwendung des Prinzips der Inversion of Control (IoC), bezieht sich aber nur auf die Erzeugung und Initialisierung von Objekten. Objekten. Sie kann als Verallgemeinerung der Fabrikmethoden verstanden werden. Die Funktionalität bleibt trotz dieser Kontrollumkehr als Einfügung enthalten. Dadurch ist es einfach möglich, Abhängigkeiten zu erkennen. - fördert lose Kopplung - Objekte erhalten ihre Abhängigkeiten passiv 1.5 Aspektorientierung wiki Aspektorientierte Programmierung (AOP) ist ein Programmierparadigma, eine Methode der ComputerComputerprogrammentwicklung, die anstrebt, verschiedene logische Aspekte eines Anwendungsprogramms (kurz (kurz Anwendung) Anwendung) getrennt voneinander zu entwerfen, zu entwickeln und zu testen. Die getrennt entwickelten Aspekte werden dann zur endgültigen Anwendung zusammengefügt. - erlaubt kohäsive (zusammenhängende) Entwicklung - Seperation of Concern - trennt Business-Logik von Systemservices - Logging - Auditing - Transaktionsverwaltung © 2010 >> Stephan Metzler >> V 4.0 >> Seite 13 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform 1.6 Maven wiki Maven ist ein BuildBuild-ManagementManagement-Tool der Apache Software Foundation und basiert auf Java. Java. Mit ihm kann kann man insbesondere JavaJava-Programme standardisiert erstellen und verwalten. Eigenschaften - bildet "Convention over Configuration" für gesamten Zyklus der Softwareerstellung ab - automatisiert die Prozesse der Entwicklung - Kompilieren - Testen - Packen - Deployen - definiert vorgegebene Standards - braucht wenige Konfigurationseinstellungen - vereinfacht Aufgaben des Build-Managements - bildet den Lebenszyklus eines Softwareprojekts ab Maven Lebenszyklus Softwareentwicklung (mit Maven) folgt einem Zyklus: - validate (Validieren) - prüft ob die Projektstruktur gültig und vollständig ist - compile (Kompilieren) - kompiliert den Quellcode - test (Testen) - testet den kompilierten Code mit einem passenden Testframework (z.B. JUnit) - package (Verpacken) - der kompilierte Code wird mit nichtkompilierbaren Dateien zur Weitergabe verpackt (z.B. JAR) - integration-test (Test der Integrationsmöglichkeit) - Softwarepaket wird auf eine Umgebung (z.B. Server) geladen und seine Funktionsfähigkeit geprüft - verify (Gültigkeitsprüfung des Software-Pakets) - prüfen ob das Softwarepaket eine gültige Struktur und bestimmte Qualitätskriterien erfüllt - install (Installieren im lokalen Maven-Repository) - installiert das Softwarepaket in dem lokalen Maven-Repository (z.B. für modulare Projekte) - deploy (Installieren im entfernten Maven-Repository) - installiert das Softwarepaket auf einem entfernten Maven-Repository (Wiederverwendbarkeit) © 2010 >> Stephan Metzler >> V 4.0 >> Seite 14 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Konfigurationsdatei http://maven.apache.org/pom.html - als XML-Datei mit dem Dateinamen pom.xml (für Project Object Model) - enthält alle Informationen zum Softwareprojekt - standardisiertes Format / Dateistruktur - Abhängigkeiten <modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId> - Informationen für Plugins <artifactId>spring-utility</artifactId> - Produkteinformationen <version>1.0.0.CI-SNAPSHOT</version> <name>Spring Utility</name> - aktuelle Version <url>http://www.springframework.org</url> <properties> <spring.framework.version> 3.0.2.RELEASE </spring.framework.version> </properties> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> <scope>test</scope> Standard-Verzeichnisstruktur - vereinfacht die zentrale Konfigurationsdatei pom.xml - Softwareprojekt soll sich an folgende Struktur halten - src/main - Eingabedateien für Erstellung des eigentlichen Produkts - src/main/java - Java-Quelltext - src/main/resources - Dateien für die Übersetzung oder zur Laufzeit z.B. Properties-Dateien - src/test - Eingabedateien für automatisierte Testläufe - src/test/java - JUnit-Testfälle für automatisierte Tests - target/classes - kompilierte Java-Klassen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 15 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Auflösung von Abhängigkeiten als zentrale Repositories - in der pom.xml werden Softwareabhängigkeiten angegeben - diese Abhängigkeiten werden aufgelöst - Maven ermittelt ob die benötigten Dateien in einem lokalen Verzeichnis bereits vorhanden sind - oder Maven versucht sich mit einem konfigurierten Maven-Repository im Intranet zu verbinden - oder Maven versucht sich mit einem konfigurierten Maven-Repository im Internet zu verbinden - Abhängigkeiten werden in das lokale Repository kopiert - Bekannte öffentliche Maven-Repositories http://mvnrepository.com/ - Apache - Ibiblio - Codehouse - Java.Net - Firmenweite Maven-Repositories stellen Bibliotheken und Frameworks zur Verfügung - Archiva, Artifactory, Proximity - Codehaus Maven Proxy - Dead Simple Maven Proxy 1.7 - Log4J populäre JAVA Logging-API http://logging.apache.org/log4j Vererbung von Loggern Logger Hierarchien erlauben feingranulare Kontrolle über Logausgaben Log-Anweisungen lassen sich durch Konfigurationsdateien ein- und ausschalten Komponenten - Loggers Layouts Appenders Loggers - benannte Entitäten (Case sensitive) und folgen einer hierarchischen Namenskonvention - Root-Logger (z.B. org) ist oberste Instanz - org.apache.log4j - Einem Logger kann ein Level zugeordnet werden - DEBUG < INFO < WARN < ERROR < FATAL © 2010 >> Stephan Metzler >> V 4.0 >> Seite 16 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Layouts erlauben das Formatieren der Loggermeldungen mit Pattern org.apache.log4j Pattern Zweck c Category: Kategorie = Name org.apache C Class = Klassennamen d Date. Beispiel: %d{HH:mm:ss,SSS} F Filename l Location. Aufrufende Methode, Quelle, Dateiname und Zeilennummer L Line number m Meldung selbst M Methodennamen n Line-Separator (Plattformabhängig) p Priority: INFO, WARN, ERROR etc. r Anzahl der Millisekunden seit dem Start der VM Appenders Destinationen für Logger Meldungen - Konsolen Dateien (klassische Logger-Dateien) GUI-Komponenten Remote Socket-Server (Stichwort zentrale Überwachung) JMS (Java Message Server) NT Event Logger Unix Syslog Deamon Appender Additivity Logger Appender Target Vererbte Appenders root org org.apache org.apache.log4j A1 B1, B2 none C1 org und root org und root org.apache.log4j, org und root A1 A1, B1, B2 A1, B1, B2 A1, B1, B2, C1 © 2010 >> Stephan Metzler >> V 4.0 >> Seite 17 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform Konfiguration - mittels XML (log4j.properties) oder mit Properties-Dateien # der Root-Logger hat den Level DEBUG log4j.rootLogger=DEBUG, stdout, file # Appender mit der Destionation Konsole log4j.appender.stdout=org.apache.log4j.ConsoleAppender # Layout Für diesen Appender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Datum im ISO-Format ISO-8601 anzeigen log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n # Konfiguration der Log-Datei log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=../log4j.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%p %t %c - %m%n log4j.appender.file.MaxFileSize=100KB # Eine Backup-Datei behalten log4j.appender.file.MaxBackupIndex=1 # Persistenz log4j.category.org.hibernate.SQL=DEBUG for debugging datasource initialization log4j.category.test.jdbc=DEBUG Aufgabe ►Log4J - Fügen Sie Ihren Projekten eine Log4J Datei hinzu - Testen Sie die verschiedenen Loggers, Layouts und Appenders - Definieren Sie eine Output Datei für die DEBUG Meldungen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 18 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java Plattform B Verteilte Systeme Lerninhalte Eigenschaften Technologien - Corba DCOM .NET EJB © 2010 >> Stephan Metzler >> V 4.0 >> Seite 19 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Verteilte Systeme 2 Verteilte Systeme - mehreren Prozessen - kommunizieren mittels Nachrichtenaustausch Eigenschaften - gemeinsame Nutzung von Ressourcen - zuverlässige und konstante Zugriffszeit - Offenheit - Erweiterbarkeit des Systems (Hardware, Software) - Standardisierung von Schnittstellen - Interprozesskommunikation - heterogene HW- und SW- Komponenten - Skalierbarkeit - ohne Änderungen der System- oder Anwendungssoftware - Fehlertoleranz - Hardwareredundanz - Softwareredundanz 2.1 Technologien für Verteilte Systeme CORBA Common Object Request Broker Architecture - plattform- und sprachunabhängig - nur "basic distribution" DCOM Distributed Component Object Model - Dienste zur Kommunikation zwischen Prozessen - Microsoft - CORBA-DCOM Bridge © 2010 >> Stephan Metzler >> V 4.0 >> Seite 20 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Verteilte Systeme .NET Microsoft http://de.wiki.org/wiki/.NET - sprach- und (plattform-) unabhängig löst Component Object Model ab fokussiert auf Client (Services) auch PDA (Personal Digital Assistant) seit Januar 2008 OpenSouce CLR ist die Laufzeitumgebung - CLR = Common Language Runtime Interpreter für den standardisierten Zwischencode - CLI ist der Zwischencode - CLI = Common Intermediate Language EJB Enterprise Java Beans http://de.wiki.org/wiki/Enterprise_JavaBeans - nur JAVA http://java.sun.com/javaee entwickelt für Geschäftsprozesse intgegriete Verbindungslogik standardisierte Komponenten vereinfachte Entwicklung - Sicherheit Transaktionen Kommunikation - synchron - asynchron © 2010 >> Stephan Metzler >> V 4.0 >> Seite 21 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Verteilte Systeme C Java EE Lerninhalte Spezifikation Einsatzgebiete Komponenten © 2010 >> Stephan Metzler >> V 4.0 >> Seite 22 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java EE Plattform 3 Java EE Plattform http://java.sun.com/javaee/5/docs/tutorial/doc/ Spezifikation - JEE ist die Spezifikation einer Softwarearchitektur - JEE bezeichnet ein Applikationsframework, ausgelegt auf - Performance - Skalierbarkeit - Plattformunabhängigkeit Eigenschaften - sauber implementierte Trennung zwischen Tiers - dadurch weitgehende Unabhängigkeit © 2010 >> Stephan Metzler >> V 4.0 >> Seite 23 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java EE Plattform 3.1 Application Server wiki Ein Anwendungsserver ist ein Server in einem Computernetzwerk, Computernetzwerk, auf dem AnwendungsAnwendungsprogramme ausgeführt werden. Im engeren Sinne bezeichnet der Begriff eine Software, Software, die spezielle Dienste zur Verfügung Verfügung stellt, wie beispielsweise Transaktionen, Transaktionen, Authentifizierung Authentifizierung oder den Zugriff auf Verzeichnisdienste und Datenbanken über definierte Schnittstellen. Schnittstellen. JEE Anwendungserver beinhaltet - Components - Applets, Servlets, Enterprise Java Beans - Containers - Web Browsers, Servlet Engines, EJB Containers - Resources - SQL Datenquellen, Nachrichtensysteme, Mailsysteme 3.2 History History der Java Enterprise Edition http://de.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition Robustheit J2EE 1.3 J2EE 1.2 JPE Project Java Plattform for the Enterprise 1998 Servlet /JSP EJB 1.0 JMS 1.1 JTA 1.0 JAAS 1.0 JNDI RMI/IIOP 1999 EJB 2.0 2001 Web Services J2EE 1.4 EJB 2.1 JSS 2.4 JSP 2.0 WS 1.0 JavaMail 1.2 JAXP 1.2 JCA 1.5 2003 SOA Java EE 5 EJB 3.0 JPA 1.0 JSS 2.5 JSP 2.1 JSF 1.2 WS 1.2 JavaMail 1.4 JAXB 2.0 JAXP 1.3 JAX-WS 2.0 StAX 1.0 JSTL 1.2 Java EE 6 2006 2010 EJB 3.1 JPA 2.0 JSS 3.0 JSF 2.0 Bean Validation © 2010 >> Stephan Metzler >> V 4.0 >> Seite 24 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java EE Plattform 3.3 Features - EJB Enterprise Java Beans - beinhalten die Geschäftslogik einer Enterprise Anwendung - gestatten Zugriff auf persistente Daten - die Beans laufen in einem EJB-Container - Session-Beans, implementieren die Geschäftslogik und sind meistens vom Client zugreifbar Message-Driven-Beans, für die Verarbeitung von JMS-Nachrichten Entity-Beans für die Abbildung von persistenten Datenobjekten - JSS Java Servlet API - Erweiterung von Servern, deren Protokoll auf Anfragen und Antworten basiert - JSP JavaServer Pages - Textdokumente, bestehen aus statischem Text und dynamischen Textelementen - WS Web Services - definieren Schnittstellen zu EJBs, die durch den URI eindeutig identifizierbar sind - JNDI Java Naming and Directory Interface - gemeinsame Schnittstelle mit der Klassen auf Namens- und Verzeichnisdienste zugreifen können - JMS Java Message Service - ist API für die asynchrone Nachrichtenverarbeitung - JTA Java Transaction API - erlaubt der Anwendung die Steuerung der Transaktionsverwaltung - ist die Java-Schnittstelle zu Transaktionsmonitoren, z.B. Java Transaction Service (JTS) - JAAS Java Authentication and Authorization Service - eine Java-API um Dienste zur Authentifikation und Zugriffsrechte bereitzustellen - implementiert ein Standard-"Pluggable Authentication Module" (PAM) - JavaMail JavaMail - erlaubt den Zugriff auf Mail Services, wie z.B. SMTP, POP3, IMAP oder NNTP - JAXB Java Architecture for XML Binding - ermöglicht es, ein XML-Schema direkt an Java-Klassen zu binden - JAXP Java API for XML Processing - hilft bei der Bearbeitung von XML-Dokumenten - JAX-RPC Java API for XML-Based Remote Procedure Calls - ermöglicht den entfernten Zugriff auf RPC-Dienste - JACC Java Authorization Contract for Containers - definiert diverse Sicherheitsrichtlinien für die diversen Java-EE-Container - JCA J2EE Connector Architecture - dient dazu, andere Systeme transparent zu integrieren © 2010 >> Stephan Metzler >> V 4.0 >> Seite 25 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java EE Plattform - JAF JavaBeans Activation Framework - bietet die Möglichkeit, verschiedene Daten anhand des MIME-Headers zu erkennen - JAX-WS Java API for XML Web Services - hilft bei der Erstellung von Web Services und zugehörigen Clients, die über XML kommunizieren, z. B. über SOAP - JPA Java Persistence API - stellt eine einheitliche und datenbankunabhängige Schnittstelle für Object-Relational-Mapping und das Arbeiten mit Entitäten bereit - StAX Streaming API for XML - cursor-basierte XML-Verarbeitung in Ergänzung der DOM- und SAX-Parser - JSF Java Server Faces - Mit Hilfe von JSF kann der Entwickler auf einfache Art und Weise Komponenten für Benutzerschnittstellen in Webseiten einbinden und die Navigation definieren - JSTL JavaServer Pages Standard Tag Library - Sammlung von JSP-Tags für die Strukturierung, XML, SQL, Internationalisierung usw. Deployment Deskriptoren wiki Ein Deployment Descriptor (frei übersetzt "Einsatzbeschreibung") ist eine Konfigurationsdatei im Format XML. XML. Im Umfeld der Java Platform, Enterprise Edition, Edition, beschreibt diese diese Konfigurationsdatei den spezifischen Bereitstellungsprozess Bereitstellungsprozess (englisch deployment) deployment) und dazu benötigte Informationen. Informationen. - sind eine der Stärken von JEE Grundlage: JEE Rollenverständnis: Component Developer, Assembler, Deployer, etc. Idee nachträglich Settings/Verhalten anpassen zu können jedoch schnell grosse Komplexität nur durch Tools (IDEs, Xdoclet) beherrschbar Migrationshindernis © 2010 >> Stephan Metzler >> V 4.0 >> Seite 26 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java EE Plattform 3.4 Einsatzgebiete In den folgenden Gebieten finden JEE Applikationen ihren Schwerpunkt: - Datenbankzugriff dynamische Internetseiten Enterprise JavaBeans Middle-Tier Server plattformenabhängige Kommunikation Sicherheit Trennung der Anwenderschwerpunkte verteilte Systeme Web-Server-Einsatz 3.5 Architektur Funktionelle Einheiten werden als Komponenten bezeichnet und zu einer KomponentenArchitektur zusammengefasst. Dabei dominieren die folgenden Core Technologies: - JNDI (Java Naming and Directory Interface) - Zugriff auf "naming" und "directory" Systeme wie LDAP, DNS, etc. - JTA (Java Transaktion API) - Zugriff auf Transaction Systeme wie BEA Tuxedo, etc. ORACLE - JDBC (Java DataBase Connectivity) - Zugriff zu relationalen Datenbanken - JMS (Java Messaging Service ) - Zugriff zu Message Orientated Middleware, z.B. iBus ,IBM MQSeries DB2 JDBC BEATuxedo JTA JEE JNDI LDAP DNS COS JMS IBM MQSeries iBus © 2010 >> Stephan Metzler >> V 4.0 >> Seite 27 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java EE Plattform 3.6 Konventionen wiki Eine Konvention (lat. (lat. conventio „Übereinkunft, Zusammenkunft“) ist eine nicht formal festgeschriebene festgeschriebene Regel, Regel, die von einer Gruppe von Menschen aufgrund eines Konsens eingehalten wird. - Namenskonventionen mit JSR 220 nicht mehr so dominant - orientieren sich am Namensmodell von SUN™ Ansatz basierend auf dem HelloWorld EJB EJB Namens Konvention Item Syntax <name>Bean Enterprise Bean Name (DD) <name>JAR EJB JAR Display Name (DD) <name>Bean Enterprise Bean Class <name> Business Interface <name>Remote Remote Interface <name>Local Local Interface <name> Abstract Schema (DD) Beispiel HelloWorldBean HelloWorldJAR HelloWorldBean HelloWorld HelloWorldRemote HelloWorldLocal HelloWorld 3.7 Komponenten wiki Eine SoftwareSoftware-Komponente ist ein SoftwareSoftware-Element, das konform zu einem Komponentenmodell ist und gemäss gemäss einem CompositionComposition-Standard ohne Änderungen mit anderen Komponenten verknüpft und ausgeführt werden kann. also eine funktionierende Software Einheit - wird über einen JEE-Server verschiedenen Clients zur Verfügung gestellt Bestandteile - als *.ear Datei (eenterprise archive) gepackt ar - Enterprise Beans ► *.jar Datei (java archive) - eine oder mehrere Enterprise Beans - WEB-Anwendungen ► *.war Datei (web application archive) - HTML-Seiten, Servlets, JSP, Bilder - Client-Anwendungen ► *.jar Datei (java archive) - Stand-Alone Java Applikation - Deployment Descriptors ► *.xml, optionale für jede EAR Komponente - XML-Dokumente zur Integrationsbeschreibung © 2010 >> Stephan Metzler >> V 4.0 >> Seite 28 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java EE Plattform 3.8 Enterprise Archive - folgt standartisierter Struktur - ermöglicht dem Applikationsserver das Entpacken der Komponenten - erlaubt das Deployen der JEE Applikation ► EJB 3.1 - EJBs müssen nicht mehr in einem EAR-Archiv verpackt sein, sondern können einfach in einem WAR deployed werden. ► WEB-INF/classes 3.9 Verteilte Multi-Tier Applikationen Das Verteilen der Applikation definiert der "seperation of concern" Aspekt der OOA: © 2010 >> Stephan Metzler >> V 4.0 >> Seite 29 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Java EE Plattform D Testen Lerninhalte Testarten TDD TestDrivenDevelopment Unit Testing Mock Testing Integrationstests © 2010 >> Stephan Metzler >> V 4.0 >> Seite 30 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen 4 Testen wiki Ein Softwaretest ist ein Test während der Softwareentwicklung, Softwareentwicklung, um die Funktionalität einer Software an den Anforderungen Anforderungen und ihre Qualität zu messen und Softwarefehler zu ermitteln. 4.1 Testarten - Unit-Test - Units sind einzelne Objekte - isoliertes Verhalten wird getestet - Integrationstest - mehrere Objekte bilden ein Workflow - deren Interaktion wird getestet - Lasttest - Skalierbarkeit des Workflows - grosse Anzahl von Requests wird getestet - Akzeptanztest - Anforderungen an die Applikation - Grundlage zur Abnahme Testverfahren die Praxis beschreibt eine Kombination von Testverfahren - ZIEL: aussagekräftiges Ergebnis - Review – prüft das Ergebnis (Ziel) - Audit – prüft die Vorgehensweise und den Ablauf (Weg ins Ziel) - BlackBlack-BoxBox-Test – prüft definierte Schnittstellen (Funktionalität) - WhiteWhite-Box-Test – prüft die Details der Logik (Codereview) - Durchführung - Testprotokoll (wer, wozu, wie, was wird getestet) - Programm (Test-Case beschreibt Testfall) die Praxis verlangt Automatisierung der Testverfahren wiki Vor allem bei testgetriebener Entwicklung ist die Testautomatisierung besonders wichtig. Tests werden im Idealfall nach jeder Änderung ausgeführt. Bei nicht automatisierten Tests ist der Aufwand so gross, dass häufig auf die Tests verzichtet wird. © 2010 >> Stephan Metzler >> V 4.0 >> Seite 31 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen 4.2 funktional vs. nicht-funktional funktionale Tests ► Benutzeranforderungen - gemäss Anforderungen - was macht das Programm - beschrieben durch Use Case nichtnicht-funktionale Tests ► Qualitätsanforderungen - Integration - Zusammenarbeit der einzelnen Teile, z.B. Server, DB, etc. - Belastung - Multi-User Verhalten - Akzeptanz - Kunde, Benutzer, etc. Softwaretests steigern Qualität der Software eXtreme Programming - alternativer Ansatz - senkt Softwareentwicklungskosten - orientiert an Bedürfnissen der Kunden Der Kunde bekommt das, was er braucht, und dann, wenn er es braucht. braucht. - XP (eXtreme Programming) baut auf - Kommunikation ►Auftraggeber - Einfachheit ► klare Schnittstellen - Feedback ► Testen (TDD) - Courage ► "code a little, test a little" © 2010 >> Stephan Metzler >> V 4.0 >> Seite 32 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen 4.3 Test Driven Development TDD ist Aspekt von Extreme Programming - einfache Entwicklung in der Erstellung von Software - komplexe Softwaresysteme in kleinen und einfachen Schritten entstehen lassen - Tests des Designs und der Implementierung stehen im Vordergrund - definiert Test, der die Funktion eines kleinen Teils des Systems beschreibt - Treffen von Design-Entscheidungen sind nicht in der Startphase erforderlich - Code muss nicht von Anfang an richtig sein, dieser wird kontinuierlich refaktoriert - Ausführung mit Hilfe von (Software)-Tools - z.B: JUnit (http://junit.org/) meist verbreitet - durch Assertion (Engl: Aussage, Behauptung) - asserts(), assertNotNull(), assertEquals(), etc. // SYNTAX : Assertion < Assertion> ( <testen> <Kriterium> <gegeben> ) // Beispiel gegeben : 3 assert( 1 + 2 == 3 ) Kriterium : EQUALS testen : 1 + 2 TDD Konzept definiert Unittests und Refaktorierungen - erstellen (Logik schreiben) - Test beschreibt, wie sich ein kleiner Teil der Software (Unit) verhalten soll - testen (erfolgreiche Tests definieren) - Design des Codes ist zweitrangig - wichtig, dass der Test erfolgreich läuft - aufräumen (schönerer Code schreiben) - mittels Refaktorierung (Umorganisation) überarbeiten, bis der Test wieder fehlerfrei läuft © 2010 >> Stephan Metzler >> V 4.0 >> Seite 33 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen 4.4 JUnit wiki JUnit ist ein Framework zum Testen von JavaJava-Programmen, das besonders für automatisierte UnitUnit-Tests einzelner Units (meist Klassen oder Methoden) Methoden) geeignet ist. ist Framework ► www.junit.org - erlaubt Werte und Bedingungen zu testen, die erfüllt sein müssen die Klasse Assert definiert eine Vielfalt von assert Methoden unterstützt das Testen von Programmen ein einfacher Test definiert public class BasicTest { public void setUp() { ... } public void testFirstThing() { assert...(...); } public void testSecondThing() { assert...(...); } public void tearDown() { ... } } Aufbau - die Methode setUp() initialisiert den Testcase - die Test-Methoden (Testcase) fangen mit test an - testFristThing() - testSecondThing() - die Methode tearDown() finalisiert den TestCase - Assertions überprüfen die Test-Methoden - Erfüllen von Anforderungen - Einhalten von Bedingungen - Exceptions sollten nicht gefangen (catch) werden - Test-Methoden Exceptions soll Exception werfen - JUnit-Framework kann dann passend darauf reagieren - Ausführen von Tests - Testklasse in Eclipse ausführen ► Run As ►JUnit Test © 2010 >> Stephan Metzler >> V 4.0 >> Seite 34 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen JUnit Annotaions ►JUnit 4 - Testfunktionen werden als statische methoden importiert import import import import import org.junit.Test; org.junit.Before; static org.junit.Assert.assertEquals; static org.junit.Assert.assertNotNull; static org.junit.Assert.assertTrue; public class TestHelloWorldBean { ... @Test(expected = NamingException.class) public void noEcho() throws NamingException { ... JUnit 4 Annotaions Begriff Beschreibung kennzeichnet Methoden als ausführbare Testfälle @Test markiert Setup-Aufgaben, die für jeden Testfall wiederholt werden sollen @Before markiert Teardown-Aufgaben, die für jeden Testfall wiederholt werden sollen @After @BeforeClass markiert Setup-Aufgaben, die nur einmal pro Testklasse ausgeführt werden sollen markiert Teardown-Aufgaben, die nur einmal pro Testklasse ausgeführt werden sollen @AfterClass kennzeichnet temporär nicht auszuführende Testfälle @Ignore 4.5 EJB UnitTests EJB bietet den Vorteil der Abstraktion - stellt Schnittstellen zur Verfügung ► Integration - läuft im EE und SE Umfeld ► Independency - lose Koppuelung der Dienste ► Isolation Ziel: jede Klasse in Isolation testen TD TDD - In der Praxis lassen sich Klassen oft nicht isoliert testen - durch Abhängigkeiten von Geschäftsdarten - durch Integration durch Workflow Lösungsansätze Begriff Beschreibung Stub fragmentale Implementierung als Stellvertreter Dummy Ersatzklasse, um das Verhalten zu testen Mock dynamisches Dummy ► konfigurierbar © 2010 >> Stephan Metzler >> V 4.0 >> Seite 35 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen 4.6 Mocks wiki Mock Mock--Objekte werden in der Testgetriebenen Softwareentwicklung DummyDummy-Objekte oder Attrappen genannt, die als Platzhalter für echte Objekte innerhalb von Unit Unit-Tests verwendet werden. - dem zu testenden Objekt wird ein Stellvertreter zugewiesen ► Mock - referenzierte Objekte lassen sich einfach ersetzen Vorteile - einzelne Klassen können isoliert getestet werden - alle referenzierten Klassen werden durch Mocks ersetzt - Tests sind performant - keine Datenbanken notwendig ► Mocks sind transient - keine Verteilten Ressourcen notwendig ► Mocks sind lokale Ressourcen - Fehlerverhalten kann leicht provoziert/simuliert werden - durch Ausnahmen ► z.B. HostNotFoundException - durch Konfiguration ► z.B. NullPointerException - durch Workflow ► z.B. SqlException 4.6.1 Mock Testing Isoliertes Testen ist in der Praxis oft nicht möglich! Mocktesting erlaubt nur reduziert eine sinnvolle Alternative. - Mock-Objekte überprüfen Interaktion mit Umgebung - Umgebung nicht vorhanden ► asynchrone Kommunikation - oder sehr zeitaufwändig ► keine Daten vorhanden - implementieren Schnittstelle - Mock-Objekt liefert keine Echtdaten ► simuliert Geschäftsprozess - nur festgelegte Testdaten ► wenn simulierte Abläufe möglich sind - Mock-Objekte sind nur limitiert einsetzbar - Objekt liefert keine deterministische Ergebnisse ► keine aktuellen Daten wie Uhrzeit, Temperatur - Objekt basiert nicht auf Interaktion ► kein Testen von Benutzungsoberflächen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 36 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen Ablauf - Mock Objekt eines Proxy erzeugen ► myBankMock - erwartetes Mock Verhalten aufzeichnen - Funktion testen public void test_getZinssatz() { BankBean toTest = this.getBeanToTest(); assertNotNull(toTest); final Mock myBankMock = this.getMockControl(Bank.class); assertNotNull(myBankMock); final SessionBean zins = new MockedSessionBean(); // instrument mock myBankMock.expects(once()).method("getRate").will(returnValue(zins)); // call the expected operation toTest.tellRate(); } 4.7 Integrationstest - @RunWith Annotation erlaubt das Erkennen der Abhängigkeiten z.B. @Parameters - @Parameters erlaubt parametrisierter Test @RunWith(value = Parameterized.class) public class JunitParameterizedTest { private int number; public JunitParameterizedTest (int number) { this.number = number; } @Parameters public static Collection<Object[]> data() { Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } }; return Arrays.asList(data); } @Test public void pushTest() { System.out.println("Parameterized Number is : " + number); } } - @Test(expected= …) definiert das Mockverhalten @Test(expected = NamingException.class) public void noEcho() throws NamingException { Object object = initialContext.lookup("not bound"); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 37 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen 4.8 Funktionale Tests - in der Paxis etablieren sich Werkzeuge - Fit (Framework for Integrated Test) http://fit.c2.com/ - - Bedingungen als HTML FitNesse http://www.fitnesse.org/ - Bedingungen in wiki - Testbedingungen werden formuliert und die Resultate auf einem Browser ausgegeben Aufgabe ► UnitTest - Testen Sie das HelloWorldBean mit JUnit Tests public class TestHelloWorldBean { private InitialContext initialContext; @Before public void setUp() throws NamingException { Properties properties = new Properties(); properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); properties.setProperty(Context.PROVIDER_URL, "jnp://localhost:1099"); initialContext = new InitialContext(properties); } @Test public void echo() throws NamingException { Object object = initialContext.lookup("HelloWorldBean/remote"); assertNotNull(object); assertTrue(object instanceof HelloWorld); HelloWorld hello = (HelloWorld) object; assertEquals("Server Echo : Hello EJB World", hello.echo("Hello EJB World")); } @Test(expected = NamingException.class) public void noEcho() throws NamingException { Object object = initialContext.lookup("not bound"); } } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 38 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Testen E JPA Lerninhalte Begriffe Lebenszyklus Bestandteile Generatorstategien Beziehungen Assoziationen Vererbung Collections Queries Datentypen Transaktionen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 39 >> total: 140 Seiten JPA 2.0 >> Java Framework >> ORM Object-Relation-Mapping 5 ORM ObjectObject-RelationRelation-Mapping ORM bietet grundsätzlich folgende Vorteile - Produktivität ► Vereinfachung und Objektorientierung des Datenzugriffs - Wartbarkeit ► weniger Codezeilen - Nachvollziehbarkeit ► serverseitiger Cache - Performance ► automatisierte Erstellung der SQL Statements - Unabhängigkeit ► abstrahierter Datenbankzugriff Darstellung der Entitäten durch POJOs nicht auf den Einsatz unter Java EE begrenzt - Version 2.0 lauffähig unter Java SE / ausserhalb eines EE Containers JBoss AS JPA Java Persistence API – Version 1.0 - Spezifikation für O/R Mapping - Version 3.1 JSR 220 EJB3 – Version 3.0 - Spezifikation für Kontainer Komponenten - Spezification für Managed Persitence JSR 318 Begriffserklärungen JSR 317 5.1 Hibernate - Implementation eines O/R Mapping Framework - Hibernate Core ► Definition mit XML Hibernate Annotation ► Definition per Annotations Hibernate Entity Manager ► Zugriff auf den Persistenzkontext © 2010 >> Stephan Metzler >> V 4.0 >> Seite 40 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA 6 JPA - spezifiziert durch JSR 220 / JSR 317 - spezifiziert Persistenz Framework - (Definition) aus Hibernate, TopLink und JDO entstanden - nicht auf den Einsatz unter Java EE begrenzt - lauffähig unter Java SE - als normale Java Anwendungen - ausserhalb eines Java EE Containers - Darstellung der Entitäten durch POJOs (Plain old Java Objects) - Definition der Metadaten durch Annotationen - XML (Deployment) Deskriptor-Dateien zur Angabe der Metadaten als Alternative orm.xml (Deployment) Deskriptor-Dateien überschreiben Annotationen Ziel ► Java EE zu vereinfachen 6.1 Persistenz Provider JPA erfordert einen Persistenz Provider, dieser definiert: - Entity - Java Repräsentation eines persistenten Datensatzes - Entity Klasse - serialisierbar / Default Konstruktor /private Attribute / Getter- und Setter Methoden - Persistence Unit - Beschreibung von Entity-Klassen, Data-Source und entspechende Abbildungsinformationen - Entity Manager - JPA Standard Interface, synchronisiert mit der Datenbank - Persistenzkontext - Menge aller Entitäten einer Transaktion als First Level Cache - Datenbank-Transaktion - garantiert ACID Verhalten der Datenbank © 2010 >> Stephan Metzler >> V 4.0 >> Seite 41 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA Persistezprovider JPA Standard synchronisiert mit DB Datenbank Transaktion Entity Manager garantiert ACID der DB lädt / speichert arbeitet auf Entity Objekt RepräsenRepräsentation tation eines Tupel umfasst Instanz von POJO - serialisierbar - Default Konstruktor - private Attribute - getter / setter assoziiert mit Persistence Context Menge aller Entitäten einer Transaktion FirstFirst-LevelLevel-Cache bezieht sich auf Entity Klasse Persistence Unit umfasst - Entityklassen - Datasource - Abbildungsinfos 6.1.1 Entities - leichtgewichtige, persistente Objekte als POJOs - zentraler Teil der Java Persistence API - abstrakte wie auch konkrete Java-Klassen werden verwendet - Vererbung, polymorphe Assoziationen und polymorphe Abfragen sind unterstützt - nicht von einer bestimmten Basisklasse abgeleitet - eigene Vererbungshierarchie kann verwendet werden - Bedingungen - muss einen parameterlosen Konstruktor enthalten public oder protected - muss eine Top-Level-Klasse sein nicht final - Methoden oder persistente Attribute dürfen nicht final sein - implementiert Serializable falls Instanzen "by-value" übertragen werden sollen - muss einen Primärschlüssel enthalten - Deklaration - mit Annotation @Entity - per XML orm.xml © 2010 >> Stephan Metzler >> V 4.0 >> Seite 42 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA Deklaration einer Entity mit Annotations - Markierung der Klassenattribute - oder Markierung der Getter-Methoden @Entity public class Person implements Serializable { @Id private Long id; private String name; @ManyToMany(targetEntity = Address.class) private Collection<Address> addresses; getter / setter / Konstructor / hashCode / equals / toString @Entity @Table(name="Adresse") public class Address implements Serializable { @Id private Long id; private String street; private String city; getter / setter / Konstructor / hashCode / equals / toString Deklaration einer Entity per orm.xml - Schemadefinitionen Tabellenname, Spaltennamen, etc. Relationen One:One, One:Many, Many:One, Many:Many Vererbungsstrategien Single Table, Table per Class, Joined Ladestrategien Objekte, Attribute Generatorstrategien für den Primarykey Sequence, Table, Hi-Lo Algorithm, etc. </entity-mappings> <entity class="Person"> <attributes> <id name="id"> <generated-value strategy="AUTO" /> </id> <basic name="name" /> <one-to-many name="adresses" target-entity="Address" mapped-by="address"> </one-to-many> </attributes> </entity> </entity-mappings> © 2010 >> Stephan Metzler >> V 4.0 >> Seite 43 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA 6.1.2 Persistenzunit - erzeugt EntityManager Factory - definiert durch persistence.xml - Persistenz Unit ► referenziert durch Logik Fassade ► BankBean - Data Source ► als Kontainer Rescource - Properties ► ORM Mapping spezifisch ► Hiberbate <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="persistenceCotext/Bank"> <jta-data-source>java:jdbc/bank</jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> <property name="hibernate.show_sql" value="true" /> </properties> </persistence-unit> </persistence> 6.1.3 EntityManager - verwaltet die Entities - ist genau einem Persistenzkontext zugeordnet - Container-Managed Entity Manager - Application-Managed Entity Manager ContainerContainer-Managed Entity Manager - innerhalb eines Java EE Containers - erzeugt und schliesst den Entity Managers verwaltet JTA (Java Transaction API) Transaktionen - definiert durch Dependency Injection - JNDI Java Naming and Directory Interface ApplicationApplication-Managed Entity Manager - wird von der Anwendung selbst verwaltet - aus EntityManagerFactory - Transaktionen durch - JTA (Java Transaction API) Spring durch AOP - lokale Transaktion (z. B. JDBC Transaktion) © 2010 >> Stephan Metzler >> V 4.0 >> Seite 44 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA 6.1.4 Persistenzkontext - Menge aller Entitäten einer Transaktion - durch UC Use Case definiert - Cache - First Level Cache definiert durch Framework z.B. Hibernate @Entity @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) public class Konto implements Serializable { ... } - Second Level Cache als fremde APIs JPA 2.0 Cache APIs Second Level Cache provider Cache Provider Read-Only Read-Write Nonstrict R-W Transactional EHCache OSCache ► Opensymphony Opensymphony JBossCache ► JBoss - Gültigkeitsdauer - transaction-scoped - - entspricht der Dauer einer Transaktion nach Abschluss der Transaktion wird der Persistenzkontext geschlossen extended - ist unabhängig von einer Transaktion - kann mehrere Transaktionen umfassen - der Persistenzkontext muss manuell (Entity Manager) geschlossen werden //emf = EntityManagerFactory ist Application Managed //Neuen EntityManager erstellen EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); //Transaktion starten Person p = em.find(Person.class, new Long(1)); p.setName("Mein_Name"); p.setAddress(new Address("meine_Strasse", "mein_Ort"); em.persist(p); em.getTransaction().commit(); //Ende der Transaktion } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 45 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA 6.2 Lebenszyklus - der Persistence Provider verwaltet die Zustände eines persistenten Objektes transparent - JPA definiert transparentes O/R-Mapping Framework - Entities ist ihr eigener Zustand nicht bekannt - es ist nicht direkt möglich, eine Entity nach ihrem aktuellen Zustand zu fragen Objektzustände eine Entity definiert vier verschiedene Zustände - New - neue Entity vorübergehend, flüchtig - Removed - gelöschte Relation gelöscht - Persistent - synchronisierte Relation persistent, nicht flüchtig - Detached - unsynchronisierte Relation gelöst Entity Lifecycle new() garbage New remove() garbage refresh() find() getReference() getResultList() getSingleResult() persist() merge()** Removed persist() remove() Managed - JPA Objekt Zustandsdiagramm - Zustandsänderung durch remove() persist() refresh() merge() Operationen des Persistenzkontext - Methoden der EntityManager-Instanz - Methoden der Query-Instanz refresh() merge() detach() close()* clear()* lock() merge()** Detached * betrifft alle Instanzen des Persistenzkontext ** erzeugt persistente Instanz, Originalobjekt bleibt erhalten wirft Exception garbage persist() remove() refresh() © 2010 >> Stephan Metzler >> V 4.0 >> Seite 46 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA Entity ObjectState ► New - durch new erzeugtes Entity-Objekt als normales Java-Objekt POJO - keine Verbindung zwischen der Entity und Entity Manager - Zustand der Entity nicht persistent abgespeichert - Garbage Collector entsorgt Objekte ohne Referenz - keine Repräsentation der Entity innerhalb der Datenbank - alle Daten der Entity sind flüchtig und gehen verloren (Garbage Collector) - Entities sind transient, nicht Teil einer Transaktion - Rollback nicht anwendbar (in Transaktion) - Primärschlüsselfelder, durch den Persistenz-Manger erzeugt, sind noch nicht gesetzt Übergang von New zu Managed mit: - persist() - merge() - Referenzierung durch persistente Entity - abhängig von Kaskadierungseinstellungen der Assoziation Entity ObjectState ► Managed - Entity wird von einem Entity Manager verwaltet - Entity hat einen Primärschlüssel zugewiesen - (auch ohne) Repräsentation innerhalb der Datenbank - persist() veranlasst keine Datenbankaufrufe - Entities im persistenten Zustand sind Teil einer Transaktion - Änderungen können durch Rollback rückgängig gemacht werden - Änderung von Attributen wird erkannt - SQL UPDATE SQL INSERT - find() – erzeugt persistente Entity - ohne Übergang von New nach Managed Übergang von Managed zu Removed: - remove() © 2010 >> Stephan Metzler >> V 4.0 >> Seite 47 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA Entity ObjectState ObjectState ► Detached - schliessen des Managers mit close(...) - Zuordnung der Entities zum Manager endet - Entities sind nicht mehr Teil einer Transaktion - Änderungen werden nicht mehr mit Datenbank synchronisiert - Java-Objekte enthalten trotzdem (veraltete) persistente Daten - durch Serialisieren (und Übertragen) einer Entity in einen anderen Prozess - Transferieren des POJO in eine Remote-Anwendung Client-Request - als Transfer-Objekte zwischen Präsentationsschicht und Datenbankschicht Übergang von Detached zu Managed: - merge() - Kopie der Entity wird wieder in Persistenzkontext aufgenommen - lock() - unveränderte Entity wird wieder in Persistenzkontext aufgenommen - Parameter lockMode definiert verschiedene Lock-Modi in Verbindung mit Transaktionen Entity ObjectState ► Removed - Entity-Objekt für das Löschen markiert - wird am Ende der laufenden Transaktion gelöscht - z.B. mit flush() - kann wieder in den managed Zustand aufgenommen werden - mit persist() Übergang von Removed zu Managed mit - persist() remove() löscht die Daten der Entity innerhalb der Datenbank, JavaJava-Objekt bleibt verfügbar, vorausgesetzt, vorausgesetzt, es wird noch referenziert © 2010 >> Stephan Metzler >> V 4.0 >> Seite 48 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA 6.3 Bestandteile eines O/R Mapping Frameworks Entities - leichtgewichtige, persistente Objekte - lösen die schwergewichtigen Entity Beans ab - zentraler Teil der Java Persistence API - abstrakte wie auch konkrete Java-Klassen werden verwendet - Vererbung, polymorphe Assoziationen und polymorphe Abfragen sind unterstützt - nicht von einer bestimmten Basisklasse abgeleitet - eigene Vererbungshierarchie kann verwendet werden - Entities und Java-Klassen können beliebig kombiniert werden - Entity-Klasse muss mit der Annotation @Entity markiert werden - Entity-Klasse muss einen parameterlosen Konstruktor enthalten (public oder protected) - Entity-Klasse muss eine Top-Level-Klasse sein, darf nicht als final deklariert sein - Methoden oder persistente Attribute der Klasse dürfen nicht final sein - das Interface Serializable muss implementiert werden - - falls Instanzen der Klasse "by-value" übertragen werden sollen jede Entity muss einen Primärschlüssel enthalten Beschreibung durch Annotations - innerhalb der Entity-Klassen - die persistenten Attribute - mit Mapping- und anderen Metadaten - Markierung der Klassenattribute Markierung der Getter-Methoden Die Markierung persistenter Attribute muss muss innerhalb einer Klasse identisch sein. Typen von persistenten Attributen: - alle primitiven Javatypen und deren Wrapperklassen / java.lang.String serialisierbare Javaklassen (z. B. java.math.BigInteger, java.math.BigDecimal, etc.) selbstdefinierte serialisierbare Javaklassen Enums java.util.Collection, java.util.Set, java.util.List, java.util.Map Collections von Entity-Klassen Embeddable Klassen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 49 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA 6.3.1 Primärschlüssel - einfaches Attribut der Klasse ► @Id - alle primitiven Javatypen - java.lang.Long / java.lang.String / java.util.Date / java.sql.Date - java.math.BigInteger / java.math.BigDecimal ► Praxis ? - Primärschlüsselklasse ► @IdClass - die Klasse muss das Serializable Interface implementieren - die Methoden equals und hashcode müssen definiert werden - die Klasse muss public sein und einen parameterlosen Konstruktor enthalten - zusammengesetzter Schlüssel ► @EmbeddedId - Instanzvariable vom Typ der Primärschlüsselklasse wird definiert als Embeddable Klasse - Entity-Klasse enthält einzelne Felder des Primärschlüssels Innerhalb einer Vererbungshierarchie von Entities darf nur ein Primärschlüssel definiert werden. Auss Ausserdem sserdem muss er in der obersten Klasse der Hierarchie deklariert sein. 6.4 Beziehungen zwischen Entities Embeddable Klassen - durch die Annotation @Embeddable markiert ► nicht @Entity - dieselben Bedingungen wie die Entity-Klasse - keinen Primärschlüssel - die persistenten Attribute der embedded Klasse werden auf die gleiche Tabellenzeile wie die der Entity Klasse gemappt - embedded Klasse gehöret zur Entity und kann nicht von mehreren Entity Objekten referenziert werden Sekundärtabellen - deklariert Instanzvariable als Value-Typ - bildet Value-Typ in eigene Tabelle ab Relationship - 1 : 1 ► @OneToOne - 1 : n / n : 1 ► @OneToMany / @ManyToOne - n : m ► @ManyToMany © 2010 >> Stephan Metzler >> V 4.0 >> Seite 50 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA undirektionale undirektionale Beziehungen - vom Anwenderfall definiert ► UCs - einfachere Strategie bidirektionale Beziehungen - unterscheiden zwischen "Besitzer" und der referenzierten Seite - Besitzer durch Userverhalten (UC) definiert referenzierte Seite muss auf ihren Besitzer durch mappedBy verweisen @Entity public class Person implements Serializable { @Id private Long id; ... @ManyToOne private Address address; ... @Entity @Table(name = "Adresse") public class Address implements Serializable { @Id private Long id; ... @OneToMany(mappedBy = "address") private Collection<Person> persons; 6.4.1 Vererbung - Polymorphe Assoziationen - als Beziehungen auf verschiedene konkrete Klassen innerhalb einer Vererbungshierarchie - Polymorphe Abfragen - liefern verschiedene konkrete Klassen einer Vererbungshierarchie zurück - können sich auf abstrakte Entities beziehen - liefern immer Instanzen von konkreten Subklassen als Ergebnis - abstrakte Klassen - können mit @Entity definiert werden - können nicht direkt instanziiert werden - MappedSuperclass - deklariert Superklasse einer Entity - wird nicht direkt einer Tabelle zugeordnet - - Attribute werden auf die Tabellen der abgeleiteten Entity-Klassen gemappt kann nicht direkt mittels einer Abfrage gesucht werden - Verwendung in einer Entity-Relationship ist nicht direkt möglich © 2010 >> Stephan Metzler >> V 4.0 >> Seite 51 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA Vererbungsstategien - SINGLE_TABLE - eine Tabelle für die ganze Hierarchie - Diskriminator Spalte - Polymorphe Abfragen sind möglich - TABLE_PER_CLASS - Eine Tabelle pro konkreter Entity-Klasse - Unterstützung durch Implementierung optional - jede Tabelle enthält ALLE Attribute - - inklusive der geerbten keine polymorphen Abfragen möglich SQL UNION als Behelf - JOINED - eine Tabelle je Superklasse und je abgeleitete Entity-Klasse - eine Tabelle je Klasse einer Vererbungshierarchie - jede Tabelle enthält spezifische Attribute der jeweiligen Klasse - polymorphe Abfragen sind möglich (nicht sehr performant) 6.5 Persistenzkontext - erzeugt EntityManager Factory - definiert durch persistence.xml - durch Dependency Injection - in der Fassade ► BankBean 6.6 EntityManager - verwaltet die Entities - stellt die API für den Zugriff auf einen Persistenzkontext bereit - einem Entity Manager ist immer genau ein Persistenzkontext zugeordnet - Container-Managed Entity Manager - Application-Managed Entity Manager Persistenzkontext bezeichnet Menge von EntityEntity-Objekten die innerhalb der Datenbank höchstens ein JavaJava-Objekt im Kontext repräsentieren © 2010 >> Stephan Metzler >> V 4.0 >> Seite 52 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA EntityMana EntityManager definiert: definiert: - Entity-Lifecycle - auch durch EM Lifecycle - Praxis ► Transaktion - Praxis ► Use-Case - Queries - NamedQueries - wiederverwendbar - NativeQueries - ANSI SQL - CriteriaQuerie - OO Ansatz - Finderfunktionalitäten - wenn PK bekannt - Ladestategien - transaktionales Verhalten - feingranular - sperren ► lock - erweitern ►join ContainerContainer-Managed Managed Entity Manager ►@PersistenceContext - kommen innerhalb eines Java EE Containers zum Einsatz - Container ist für das Erzeugen und Schliessen des Entity Managers verantwortlich - der Java EE Container verwaltet JTA Java Transaction API - Verwaltung geschieht transparent für die Anwendung - Zugriff auf den Entity Manager erhält die Anwendung durch - Dependency Injection - JNDI ApplicationApplication-Managed Entity Manager - Entity Manager wird von der Anwendung verwaltet - zum Erzeugen wird eine EntityManagerFactory verwendet - Transaktionen durch - JTA Java Transaction API - lokale Transaktion ► z.B. JDBC Transaktion © 2010 >> Stephan Metzler >> V 4.0 >> Seite 53 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA Gültigkeitsdauer eines Persistenzkontexts - transaction-scoped - entspricht der Dauer einer Transaktion Transaktion definiert den PesistenceContext - der Persistenzkontext wird geleert - die Entities detached und numanaged - extended - ist unabhängig von einer Transaktion - aber nur innerhalb der JVM gültig ► Applikationserver - kann mehrere Transaktionen umfassen - Persistencekontext bleibt erhalten - Entities werden automatisch synchronisiert - persit() oder merge() ist nicht notwendig - Persistenzkontext wird manuell verwaltet - durch schliessen des Entity Manager Methoden Methoden der EntityManager API (Ausschnitt) public void persist(Object entity); - Übergang zu managed Entity Instanz ► commit() / flush() persistiert Objekt - ist entity eine neue Entity wird diese zur managed Entity - ist entity eine bestehende managed Entity so wird nichts geschehen - ist entity eine removed Entity wird diese zur managed Entity - ist entity eine detached Entity wird eine IllegalArgumentException geworfen - gilt auch für relationale Felder von entity die mit CascadeType.PERSIST annotiert sind public void remove(Object entity); - Übergang zu removed Entity Instanz ► commit() / flush() löscht Objekt - ist entity eine neue Entity so wird nichts geschehen - ist entity eine bestehende managed Entity so wird diese gelöscht - ist entity eine removed Entity so wird nichts geschehen - ist entity eine detached Entity wird eine IllegalArgumentException geworfen - gilt auch für relationale Felder von entity die mit CascadeType.REMOVE annotiert sind © 2010 >> Stephan Metzler >> V 4.0 >> Seite 54 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA public void refresh(Object entity); - synchronisiert die Entity Instanz mit der Datensource ► überschriebt Entity - ist entity eine neue Entity wird eine IllegalArgumentException geworfen - ist entity eine bestehende managed Entity so wird diese mit der Datensource synchronisiert - ist entity eine removed Entity wird eine IllegalArgumentException geworfen - ist entity eine detached Entity wird eine IllegalArgumentException geworfen - gilt auch für relationale Felder von entity die mit CascadeType.REFRESH annotiert sind public void merge(Object entity); - Übergang von einer detached Entity zu einer managed Entity Instanz - ist entity eine detached Entity so wird diese in die existierende managed Instanz von entity kopiert oder eine neue Kopie einer managed entity Instanz erstellt - ist entity eine neue Entity so wird eine neue managed Instanz entity* als Kopie erstellt ist entity eine bestehende managed Entity so wird nichts geschehen ist entity eine removed Entity wird eine IllegalArgumentException geworfen gilt auch für relationale Felder von entity die mit CascadeType.MERGE annotiert sind public void detach(Object entity); - Übergang zu einer detached Entity Instanz - ist entity eine bestehende managed Entity so wird diese zu einer detached Entity - ist entity eine detached Entity so wird nichts geschehen - gilt auch für relationale Felder von entity die mit CascadeType.DETACH annotiert sind public void lock(Object entity, LockModeType mode); - Sperrt die Entity Instanz - LockModeType.READ - - andere Transaktionen können das Objekt lesen aber nicht ändern LockModeType.WRITE - andere Transaktionen können das Objekt weder lesen noch schreiben © 2010 >> Stephan Metzler >> V 4.0 >> Seite 55 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA public <T> T find(Class<T> entity, Object primaryKey); - Sucht ein Objekt - lädt die entity aus der Datenbank, welche dem Primärschlüssel zugeordnet ist - liefert null, falls keine Entity gefunden wurde public <T> T getReference(Class<T> entity, Object primaryKey); - lädt ein Proxy (bzw. eine Referenz) einer Entity - durch den angegebenen Primärschlüssel eindeutig identifiziert - übrige Felder der Entity können zu einem späteren Zeitpunkt nachgeladen werden Vorgehen ist sinnvoll, wenn eine Entity einer anderen zugeordnet werden soll und der eigentliche Inhalt gar nicht benötigt wird public boolean contains(Object entity); - prüft ob sich die Entity im Persistenzkontext des Entity Managers befindet public void flush(); - synchronisiert die Datensource mit den Entity Objekten - weist den EntityManager an, den Zustand aller Entites die dem Persistenzkontext zugeordnet sind, mit - der Datenbank zu synchronisieren Synchronisation geschieht dabei nur in eine Richtung; der Inhalt der Entity-Objekte im Persistenzkontext wird nicht aktualisiert, falls sich der Inhalt der entsprechenden Datenbankfelder geändert haben sollte. Synchronisation wird nur ausgeführt, wenn eine Transaktion aktiv ist public void clear(); - leert den Persistenzkontext des Entity Managers - Persistenzkontext des Entity Managers wird geleert - alle verwalteten Entities werden detached Entities - Synchronisation mit der Datenbank findet nicht statt © 2010 >> Stephan Metzler >> V 4.0 >> Seite 56 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA Exception des EntityManagers IllegalArgument IllegalArgumentArgument- Objekt ist keine Entity OptimisticLock OptimisticLockLockRollbackRollbackTransactionTransactionRequiredRequired- DB Inhalt wurde geändert Rollback kann nicht durchgeführt werden NoResultNoResultNoUniqueResult NoUniqueResultResult- Query.getSingleResult() liefert kein oder mehr als ein Ergebnis, kein Rollback keine laufende Transaktion joinTransction Entity existiert nicht (mehr) contains EntityNotFound EntityNotFoundFound- lock PK existiert bereits refresh EntityExistsEntityExists- flush setzt Transaktionsstatus auf RollbackOnly getReference PersistencePersistence- find Beschreibung remov remove e -Exception EntityMangers Methoden merge Exception des EntityManagers persist 6.6.1 6.7 Entity Listener - informiert über Ereignisse während des Lebenszyklus einer Entity - als Container Callback Methode - als Listener Klasse 6.7.1 Listener als Container Callback - Interception durch Container - als Lifecycle Ereignis - erweitert Persistenzmechanismus durch eigene Funktionalitäten Container Callback als EnitiyListener Annotation Beschreibung @PrePersist / @PreRemove @Post @PostPersist ostPersist / @Post @PostRemove ostRemove @PreLoad / @PreUpdate @PreUpdate @PostLoad @PostLoad / @PostUpdate @PostUpdate vor der Ausführung von EntityManger.persist() / remove() nach der Ausführung von EntityManger.persist() / remove() vor der Ausführung von EntityManger.update() / refresh() nach der Ausführung von EntityManger.load() / update() © 2010 >> Stephan Metzler >> V 4.0 >> Seite 57 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA 6.7.2 Listener als Entity-Listener-Klasse - durch @EntityListeners auf Klassenebene - Methoden werden automatisch aufgerufen - mehrere Methoden mit verschiedenen Callback Annotations können markiert werden - mehrfache Markierung einer Methode durch verschiedene Callback Annotations ist zulässig - - jedoch nur eine Methode pro Ereignis - mehrere Listener pro Entity können definiert werden - Reihenfolge abhängig von der @EntityListener Annotation - Entity Listener und Callback Methoden gemeinsam möglich - Methoden der Entity Listener werden vor den Callback-Methoden aufgerufen Callback-Methode muss die folgende Signatur haben - o ist die Entity, auf die sich die Entity-Listener-Klasse bezieht void <METHODENNAME>() void <METHODENNAME> (<KLASSE> o) Verwendung Verwendung von CallbackCallback-Methoden und Entity Entity Listenern @Entity @EntityListeners(value = { PersonListener1.class, PersonListener2.class }) public class Person implements Serializable { @PostPersist protected void postPersistPerson() { System.out.println("PostPesist Person called"); } public class PersonListener1 { @PrePersist @PostPersist protected void postPersistMethod1(Person p) { System.out.println("PrePesist/PostPesist PersonListener1called"); } } [STDOUT] PrePesist/PostPesist PersonListener1 called [STDOUT] PrePesist/PostPesist PersonListener1 called [STDOUT] PostPesist PersonListener2 called [STDOUT] PostPesist Person called public class PersonListener2 { @PostPersist protected void postPersistMethod1(Person p) { System.out.println("PostPesist PersonListener2 called"); } } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 58 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA 6.8 Queries - in SQL formuliert - durch JPA Query Language definiert ►polymorph - Massen-Updates und –Deletes - Joins - Group By - Subqueries - JPA QL ist portable ► Datenbank Unabhängigkeit - Native SQL ist proprietär - mehrer Create Methoden stehen zur Verfügung - Query - polimorphe JPA Query ► liefert Entity Objekte - NativeQuery - native SQL Query ► liefert Tabelleninhalte - NamedQuery - wiederverwendbar, parametrisierbar ► durch die Entity definiert Beispiel ► NamedQuery - definiert durch die Entity @Entity @NamedQueries({ @NamedQuery(name = "Person.findAll", query = "from Person p"), @NamedQuery(name = "Person.findByName", query = "from Person p where p.name = :name") }) public class Person implements Serializable { ... } - implementiret und parametrisiert durch die Fassade @Stateless public class BankBean implements Bank { @PersistenceContext(unitName = "persistenceCotext/Bank" ) private EntityManager manager; public void deletePerson(Person p){ Person personToDelete = (Person) manager.createNamedQuery("Person.findByName") .setParameter("name", p.getName()).getSingleResult(); manager.remove(personToDelete); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 59 >> total: 140 Seiten JPA 2.0 >> Java Framework >> JPA ResultSetMapping - benutzerdefinierte Klasse als Resultset ► native - für komplexe Abfragen für definierte Resultatlisten public PersonWithMultipleAccounts getPersonWithMultipleAccounts() { String query = "SELECT p.name, k.name FROM Person p, Konto k WHERE p.kontos.size > 2"; Query q = manager.createNativeQuery(query, "PersonWithMultipleAccounts"); return (PersonWithMultipleAccounts) q.getResultList(); } - definiert eigene ResultSetKlasse ► durch die Entity definiert @SqlResultSetMapping(name = "PersonWithMultipleAccounts", entities = { @EntityResult(entityClass = entity.Person.class, fields = { @FieldResult(name = "name", column = "name") }), @EntityResult(entityClass = entity.Konto.class, fields = { @FieldResult(name = "name", column = "name") }) }) public class Person implements Serializable { .. } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 60 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Hibernate 7 Hibernate - Open-Source-Persistenz- und ORM-Framework für Java www.hibernate.org - speichert POJOs mit Attributen und Methoden in relationalen Datenbanken - synchronisiert DB Relationen mit Objekten Vorteile - Abstraktion der verwendeten DB - dadurch DB Unabhängigkeit - nicht intrusiv - keine Ableitung eigener Klassen von Hibernate-Klassen erforderlich - keine Voraussetzungen an die Laufzeitumgebung - verwendbar managed und non-managed - Generierung von sehr effizientem SQL Nachteil Nachteil - exponentieller Komplexitätsgrad 7.1 Hibernate als Persistenzframework - implementiert die standardisierten Annotations ► somit JPA kompatible - deklariert Bedingungen durch Validators - stellt mit dem EntityManager eine Persistenzengine zur Verfügung 7.2 Hibernate Annotations - Verwendung der Hibernate eigenen Annotations ► Erweiterung der Funktionalität - Metadaten im XML-Format ►hbm.xml, resp. orm.xml bei JPA - Lade- / Speicherverhalten - Kaskadierung - Validierung - Geratorstategien für den PrimaryKey Hibernate Annotations erweitern die Persistenzfunktionalität im Umgang mit Polymorphie, Polymorphie, Assoziations Assoziations, Collections Collections und Queries. Queries. Hibernate Annotations sind immer eine Einschrenkung der Portabilität. © 2010 >> Stephan Metzler >> V 4.0 >> Seite 61 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Hibernate 7.3 Hibernate Validator - ermöglicht Deklaration von Bedingungen - die eine gültige Entity erfüllen muss - definiert Constraints - werden als Annotations direkt in der betroffenen Entity deklariert - Methoden wie auch Instanzvariablen können markiert werden - werden durch die Entity-Objekte überprüft ► z.B. durch Entity Listeners - Validator Implementierung führt die tatsächliche Überprüfung durch - Deklaration zentral ► durch die Entity - Überprüfung innerhalb einer mehrschichtigen Anwendung Hinernate Validatoren ►Ausschnitt Annotation Beschreibung Überprüfung von Stringlängen @Lenght Min-, Maximalwert für numerische Werte @Min / @Max überprüfung auf NULL @NotNull überprüft, ob ein Datum in der Vergangenheit / Zukunft liegt @Past / @Future überprüft, ob ein Attribut einem regulären Ausdruck entspricht @Pattern Wertebereich für numerische Werte @Range überprüfung der Länge von Collections, Arrays und Maps @Size überprüft boolean Werte auf false @AssertFalse überprüft boolean Werte auf true @AssertTrue führt eine Überprüfung des markierten Objekts durch @Valid überprüft Kreditkartennummern auf true @CreditCardNumber überprüft EAN-Nummern auf true @EAN überprüft Emails auf true @Email überprüft auf Digits @Digits © 2010 >> Stephan Metzler >> V 4.0 >> Seite 62 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Hibernate Beispiel ►Validierung einer Instanzvariablen import org.hibernate.validator.Length; import org.hibernate.validator.NotNull; @Entity public class Person implements Serializable { @Length(max=10) @NotNull private String name; Beispiel ► Definition von HibernateConstraints HibernateConstraints public void createPerson(Person p) { ClassValidator personValidator = new ClassValidator(Person.class); InvalidValue[] invalidValues = personValidator.getInvalidValues(p); for (InvalidValue iv : invalidValues) System.out.println(iv.getBean() + iv.getMessage()); manager.persist(p); } Output [STDOUT] Person(id=null, name=TESTPerson1, address=Address(id=null, street=Strasse1, city=Ort1, persons=null), kontos=null) muss zwischen 0 und 10 lang sein 7.4 Hibernate EntityManager - implementiert durch die Java Persistence API - Einsatz innerhalb eines Java EE Containers - Einsatz als Standalone Lösung ausserhalb eines Containers - Hibernate EntityManager - setzt auf dem Hibernate Core auf - verwendet diesen als Persistenzengine © 2010 >> Stephan Metzler >> V 4.0 >> Seite 63 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Hibernate 7.5 Hibernate Tools - Unterstützung bei der Entwicklung - Eclipse Integration - DDL Schema Generation ►hbm2ddl - von einer Hibernate Mapping-Datei - Java Source Generation ► hbm2java - von einer Hibernate Mapping-Datei - Middlegen - generierung einer Hibernate Mapping Datei - Third Party Tool SQL Kategorie Beschreibung Anwendung Data Definition CREATE DDL Language DROP DML Data Manipulation Language UPDATE DCL Data Control Language GRANT REVOKE DRL Data Retrival Language SELECT © 2010 >> Stephan Metzler >> V 4.0 >> Seite 64 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Kontoverwaltung als Anwendungsbeispiel 8 Kontoverwaltung als Anwendungsbeispiel - einfache Kontoverwaltung - Person als Kontoinhaber - Trustee als Kontoverwalter - Address - - für Person für Trustee Account als Konto - Personal - Deposit - Euro - Anwendungsfälle - Hinzufügen - - Inhaber Verwalter Konto Verwaltungsfunktionen Suchfunktionen 8.1 Konfiguration persistence.xml - definiert eine oder mehrere PersitenceUnits - JEE ► im Verzeichnis META-INF JSE ► im Verzeichis WEB-INF/classes <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="persistenceCotext/Bank"> <jta-data-source>java:jdbc/bank</jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> </properties> </persistence-unit> </persistence> © 2010 >> Stephan Metzler >> V 4.0 >> Seite 65 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Kontoverwaltung als Anwendungsbeispiel POJO als Entity - einfaches POJO Plain Old Java Object - Annotations der Java Persistence API - @Entity vor der Klassendefinition - Getter- und Setter-Methoden - Java Nameskonventionen - id als eindeutigen Bezeichner für persistente Klasse ► Praxis: Long - durch @Id annotiert - Standardkonstruktor ► auch private möglich @Transient für nicht persistente Felder Annotation @Entity ► C Parameter Beschreibung Name der Entity name Typ Default String Klassenname @Entity(name="Person") public class Person implements Serializable { Tabelle Annotation @Table ► C Parameter Beschreibung Tabellenname name Typ Default String schema Tabellenschema String catalog Tabellenkatalog String Klassenname datenbankspezifisches Schema datenbankspezifischer Katalog uniqueConstraint Unique-Constraints, die auf der Tabelle definiert werden sollen UniqueConstraint[] - Verwendung - anpassen an Legacy @Entity @Table(name = "Adresse") public class Address implements Serializable { © 2010 >> Stephan Metzler >> V 4.0 >> Seite 66 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Kontoverwaltung als Anwendungsbeispiel Fassade wiki Fassade (engl. facade facade) de) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zu der Kategorie der Strukturmuster (Structural (Structural Patterns). Patterns). Es bietet eine einheitliche und meist vereinfachte Schnittstelle zu einer Menge von Schnittstellen eines Subsystems. Subsystems. - die Entities sind nicht remote ansprechbar - haben keine Schnittstellen - werden über eine Fassade angesprochen - SLSB / SFSB - durch EntityManger ► legt Abhängigkeit zu einer EntityManagerFactory / PersistenzUnit fest Annotation @PersitenceUnit Parameter Beschreibung Beschreibung Name der EntityManagerFactory name Name der PersistenzUnit unitName Typ Default String String @PersistenceContext(unitName = "persistenceContext/Bank") private EntityManager manager; Aufgabe ►Entities verwalten - erstellen und testen Sie Funktionalitäten der Bank Fassade - Entities erstellen und löschen public void createPerson(Person p) { manager.persist(p); } public void createAccount(Konto k) { manager.persist(k); } public void deletePerson(Person p) { Person personToDelete = (Person) manager .createNamedQuery("Person.findByName") .setParameter("name", p.getName()).getSingleResult(); manager.remove(personToDelete); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 67 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Primarykey vs Businesskey 9 Primarykey vs Businesskey Anforderungen an Primärschlüssel - darf nicht null sein - kann nie verändert werden ► nicht sinvoll für einen natürlichen Schlüssel - ist in einer Tabelle über alle Einträge eindeutig Datenbankidentität, Objektidentität, Objektidentität, Objektgleichheit - Objektidentität in Java ► Referenz-Semantic mit == - zwei Objekte sind identisch, wenn sie dieselbe Adresse im Speicher der Java VM haben - Objektgleichheit in Java ► Value-Semantic mit equals - zwei Objekte sind gleich, wenn sie denselben Inhalt haben @Test public void referenceAndValueSemantic() { Person p = new Person("TestPerson", null); bank.createPerson(p); Person newPerson = bank.getPerson("TestPerson"); assertFalse (p.getName() == newPerson.getName()); // zwei Objekte assertFalse(p.equals(newPerson)); // anderer Inhalt } Prax Praxis - equals() und hashcode() immer überschreiben - equals() soll geschäftsrelevante, eindeutige Daten vergleichen hashcode() soll gute Verteilung definieren ► mehr, aber echte Daten - Problematisch bei - Objekte in Collections (Sets, Maps, etc.) - - da Implementation durch java.util.HashSet einbinden von Detached Objekten - bestehendes Objekt wird durch Entity Manger verwaltet ► PKs werden generiert Beispiel ► an einer einer Adressen wohnen zwei Personen - Adresse wird mit einer Collection von zwei Personen erstellt - Objektgleichheit über Primärschlüssel bestimmt, überschreibt das erste Objekt beim Hinzufügen Address a = new Address("Strasse", "Ort"); Collection<Person> persons = new ArrayList(); persons.add(new Person("Person3", a)); persons.add(new Person("Person3", a)); bank.createAddress(a); © 2010 >> Stephan Metzler >> V 4.0 >> Seite 68 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Generatorstrategien 10 Generatorstrategien - persistente Datenbankobjekte haben eine Identität ► PK - @Id definiert Primary Key Attribut - @GeneratedValue definiert Strategie zur Generierung des Primärschlüssels - zwei gleiche Objekte besitzen denselben Primärschlüssel - Verwalten der Primärschlüssel übernimmt Persistenz-Unit Praxisansatz PrimaryKey generieren ► in der Praxis sinnvoll - man muss sich nicht um PK kümmern ► oder FK - der Businesskey kann sich ändern ► z.B. AHV Nummer - der PK darf sich nicht ändern - Daten verlieren ihre Konsistenz - man arbeitet mit konkreten Daten ► Namen, Orte, etc. - PK ist oft ein Literal oder ein numerischer Ausdruck - oder eine Kombination beider 10.1 Generierung des Primary Key Annotation @GeneratedValue ► T Parameter Beschreibung strategy Strategie zum definieren des Primary Keys generator Name des Primärschlüsselgenerators Parameter AUTO IDENTITY SEQUENCE TABLE String Default AUTO AUTO verwendet die Strategy der Datenbank @Id @GeneratedValue private Long id; @Test public void createPerson() { Person p = new Person(); p.setName("Name"); bank.createPerson(p); bank.createPerson(p); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 69 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Generatorstrategien Generatoren für die Primärschlüssel Strategie Beschreibung AUTO TABLE wählt entsprechend der darunterliegenden Datenbank eine Strategie (TABLE, IDENTIY, SEQUENCE). Entspricht der Hibernate-Generatorstrategie native. IDs sind in einer eigenen Tabelle. Entspricht der Hibernate-Generatorstrategie hilo ► Hi/Lo Algorithmus unterstützt Identity Columns, die es beispielsweise in MySQL, HSQLDB, DB2 und MS SQL IDENTITY Server gibt. Entspricht der Hibernate-Generatorstrategie identity. SEQUENCE NCE unterstützt Sequences, die es beispielsweise in PostgreSQL, Oracle und Firebird gibt. SEQUE Entspricht der Hibernate-Generatorstrategie sequence. @Id @GeneratedValue (strategy=GenerationType.AUTO) private Long id; Annotation @SequenceGenerator ► T Parameter Beschreibung name sequenceName initalValue allocationSize eindeutiger Name innerhalb der Persistence-Unit kann von anderen Entities referenziert werden Datenbank abhängiges SequenzObjekt Anfangswert für die Generierung Schrittweite Typ Default String String int int abhängig vom Persistence-Provider 0 oder 1 50 @Id @GeneratedValue(generator = "useridgen") @GenericGenerator(name = "useridgen", strategy = "seqhilo", parameters = { @Parameter(name = "max_lo", value = "5"), @Parameter(name = "sequence", value = "mysequence") }) private Long id; © 2010 >> Stephan Metzler >> V 4.0 >> Seite 70 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Generatorstrategien Annotation @TableGenerator ► T Parameter Beschreibung Typ name eindeutiger Name innerhalb der Persistence-Unit String table Tabellenname String schema schema Tabellenschema catalog Tabellenkatalog pkColumnName Spalte für den Namen der Generatoren valueColumn valueColumnName umnName Spalte für den Zählerstand des PK pkColumnValue Generatorname initialValue allocationSize uniqueConstraints uniqueConstraints Anfangswert für die Generierung Schrittweite Definition von Constraints Default abhängig vom PersistenceProvider datenbankspezifisches String Schema datenbankspezifischer String Katalog abhängig vom PersistenceString Provider abhängig vom PersistenceString Provider abhängig vom PersistenceString Provider int 0 oder 1 int 50 UniqueConstraint[] 10.2 Definition des Primary Key - definiert eine Klasse als fachliche Kombination für den Primärschlüssel Annotation @IdClass ► E Parameter Beschreibung Typ value Class das Klassenobjekt der Primärschlüsselklasse Default @Entity(name="Person") @IdClass(PersonPK.class) public class Person implements Serializable { @Id private Long p_id; @Id private String p_context; - definiert eine eingebettete Klasse als zusammengesetzten Primärschlüssel Annotation @EmbeddedId ► M, F Parameter Beschreibung Typ Default © 2010 >> Stephan Metzler >> V 4.0 >> Seite 71 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Beziehungen 11 Beziehungen - Beziehungen zwischen Klassen – Relation zwischen Tabellen - Abbilden eines Objektmodells (Vererbung) durch Relationen in einem Datenmodel - Java Objekte werden in Relationen abgebildet - als Komponente - durch Assoziationen - uni-direktional - bi-direktional ► @mappedBy gibt führendes Ende an - N Seite als Collection - java.lang.List ► Reihenfolge der Elemente nicht gegeben ► @OrderBy - java.lang.Set java.lang.Map org.hibernate.mapping.Bag Collections Eigenschaft duplikatfrei indexiert inverse performates Update performates Inverse List Set Map Bag 11.1 Entity vs Value Komponenten EntityEntity-Komponente - haben einen Primärschlüssel - haben einen Lebenszyklus Valuealue-Komponente - haben keine Datenbankidentität - haben keinen Primärschlüssel - gehören zu einer Entity und ihr Zustand wird innerhalb der Tabelle der dazugehörigen Entity gesichert - typisch sind einfache Objekte vom Typ String - Lebensdauer eines Value-Typ ist immer an den Lebenszyklus der enstpr. Entity gebunden Komponenten ermöglichen die Abbildung mehrerer Klassen auf eine Tabelle. © 2010 >> Stephan Metzler >> V 4.0 >> Seite 72 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Beziehungen 11.2 Value Komponenten - als Beziehung Person zu Address Aggregation - dargestellt mit einer leeren Raute - beschreibt eine schwache Beziehung zwischen Objekten Objekt ist ein Teil eines anderen Objekts - kann aber im Gegensatz zur Komposition auch alleine existieren Komposition - strengere Form der Aggregation - die Lebensdauer eines Objektes Address ist dabei an das Objekt Person gebunden - eine Address wird also immer mit oder nach dem Person erzeugt - und mit dem Objekt Person zerstört - Komposition wird in UML mit einer gefüllten Raute dargestellt ► http://www.omg.org Die Implementierung mit Java macht keinen Unterschied. Aber Address ist für Persistenzprovider ein ValueValue-Typ, hat keinen Primärschlüssel. 11.2.1 Embeddable - Annotation @Embeddable definiert Komponente auf Klassenebene - ohne @Id - Entity Person mit dem Attribut address muss nicht gekennzeichnet werden - @Embedded ist optional Aufgabe ►Embadded Klasse - testen Sie die Adresse als Value-Komponente @Entity public class Person implements Serializable { @Embedded // optional private Address address; @Embeddable public class Address implements Serializable { ... } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 73 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Beziehungen 11.2.2 Sekundärtabellen - @SecondaryTable deklariert Instanzvariable als Value-Typ - @SecondaryTable definiert die Tabelle der Value-Komponente Annotation @SecondaryTable ► E Parameter name Beschreibung Beschreibung Typ Tabellenname String schema Tabellenschema String catalog Tabellenkatalog String uniqueConstraint pkJoinColumns Annotation Parameter value Unique-Constraints, die auf der Tabelle definiert werden sollen PKs der Tabellen über die die Beziehung hergestellt werden soll @SecondaryTables ► E Beschreibung Liste von SecondaryTables Default datenbankspezifisches Schema datenbankspezifischer Katalog UniqueConstraint[] PrimaryKeyCoinColumn[] alle PKs der Primärtabelle Typ Default SecondaryTable[ ] Column Persistenzprovider definiert als Spaltennamen für Komponenten den Attributnamen - Annotation @Column definiert den Spaltennamen benutzerspezifisch - @Column definiert den Namen der Tabellenspalte Annotation @Column ► T Parameter Beschreibung Typ Default name String Name des Attributs Boolean false Boolean Boolean Boolean String String int int int true true true referenzierte Spalte Primärtabelle 255 herstellerabhängig 0 unique nullable insertable updatable columnDefinition table length precision scale Spaltenname definiert eindeutiges Schlüsselfeld, kann alternative über uniqueConstraint auf Tabellenebene deklariert werden erlaubt Null-Werte, hat für primitive Java Typen keine Wirkung definiert die Insert-Funktionalität definiert die Update- Funktionalität Fragment der SQL Typendefinition Namen der Tabelle, welche die Spalte enthält Spaltengrösse ► nur für String anwendbar Anzahl Stellen ►nur für numerische Spalten Anzahl Nachkommastellen ► nur numerische Spalten anwendbar © 2010 >> Stephan Metzler >> V 4.0 >> Seite 74 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Beziehungen Aufgabe ►SecundaryTable - testen Sie die Addresse mit Instanzvariablen als Sekundärtabellen - - email ►persöhnliche Emailadresse - owned ►als Boolscher Wert @Entity @SecondaryTables( { @SecondaryTable(name = "EMAIL"), @SecondaryTable(name = "OWNED") }) public class Address implements Serializable { @Column(name = "personal_email", table = "EMAIL") private String email; @Column(name = "self_owned", table = "OWNED") private boolean owned; Aufgabe ► Column - setzen Sie die Attribute der Adresse benutzerspezifisch mit der @Column Anotation - email als unique owned als read-only @Column(name = "personal_email", table = "EMAIL", unique = true) private String email; @Column(name = "self_owned", table = "OWNED", insertable = false) private boolean owned; @Test(expected = EJBException.class) public void testReadOnlyOwnedUniqueEmail () { Address a = new Address("Strasse", "Ort", "[email protected]", true); bank.createAddress(a); bank.createAddress(a); } ERROR [org.hibernate.util.JDBCExceptionReporter] Duplicate entry '[email protected]' for key 'personal_email' © 2010 >> Stephan Metzler >> V 4.0 >> Seite 75 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Beziehungen AttributeOverride - überschreibt die Definition eines Feldes in der Superklasse - ermöglicht Wiederverwendung der Komponente Annotation @AttributeOverride ► C F M Parameter Beschreibung Typ Attribut String name Spaltenname @Column column Annotation @AttributeOverrides ► C F M Parameter Beschreibung Typ Liste von AttributeOverride AttributeOverride[] value Default Default Aufgabe ► AttributeOverride @Entity public class Person implements Serializable { @AttributeOverrides( { @AttributeOverride( name = "street", column = @Column(name = "personstreet")), @AttributeOverride( name = "city", column = @Column(name = "personcity", length = 50)) }) private Address address; © 2010 >> Stephan Metzler >> V 4.0 >> Seite 76 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12 Assoziationen - Verbindung mindestens zweier Klassen - erlaubt das Navigieren von der einen zur anderen Klasse - binäre Assoziation ist eine Beziehung zwischen zwei Klassen reflexive Assoziation definiert Beziehung zu sich selbst - Kardinalität beschreibt den Grad einer Beziehung zwischen zwei Klassen: - Eins-zu-Eins ► 1:1 ► @OneToOne - eine Klasse steht mit einer anderen Klasse in Beziehung - Eins-zu-Viele / Viele-zu-Eins ► 1:n / n:1 ► @OneToMany / @ManyToOne - eine Klasse steht mit mehreren anderen Klassen in Beziehung - Viele-zu-Viele ► n:n ► @ManyToMany - mehrere Klassen stehen mit mehreren anderen Klassen in Beziehung - Bei allen Assoziationen unterscheidet man - unidirektionale Beziehungen - - nur über eine Entity kann navigiert werden bidirektionale Beziehungen - beidseitige Navigation möglich ► Entitys müssen beidseitig Getter und Setter definieren 12.1 Überschreiben von Assoziationen - Analog zum Re-Mapping von Attributen - Re-Mappen von Beziehungen ► überschreiben der FK - @AssociationOverride resp. @AssociatenOverrides Annotation @AssociationOverride ► C F M Parameter Beschreibung Typ p Ty Attribut String name Liste von Spaltenname @JoinColumn[] joinColumns Annotation @AssociationOverrides ► C F M Parameter Beschreibung Typ Menge von AssociationOverride AssociationOverride[] value Default Default @Entity @AssociationOverride( name = "address", joinColumns = @JoinColumn(name="address_fk")) public class Person implements Serializable { ... } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 77 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12.2 Überschreiben von Fremdschlüsselbezeichnungen Annotation @JoinColumn ► F M Parameter Beschreibung Spaltenname name unique definiert eindeutiges Schlüsselfeld, kann auch über uniqueConstraint auf Tabellenebene deklariert werden erlaubt Null-Werte, hat für primitive Typen keine Wirkung definiert die Insert-Funktionalität definiert die Update-Funktionalität Fragment der SQL Typendefinition nullable insertable updatable columnDefinition referencedreferencedName der Spalte auf die referenziert wird ColumnName Annotation @JoinColumns ► F M Parameter Beschreibung value Menge von JoinColumn Annotations Typ JoinColumn[] Typ Default String Attribut Boolean false Boolean Boolean Boolean String true true true ref. Spalte String ref. PK Default 12.3 @OneToOne - bei 1:1 Beziehungen haben die beiden Tabellen den gleichen Primary-Key - Primary-Key selbst erzeugen ► nicht Business-Key verwenden - Generatorstrategie verwenden Annotation @OneToOne ► M F Parameter Beschreibung Entitätsklasse targetEntity Angabe der Kaskadierungsoperationen cascade definiert Ladeverhalten des Attribut fetch optional mappedBy erlaubt Null-Werte ► muss nicht Assoziation belegt sein hat für primitive Java Typen keine Wirkung definiert Attribut der führenden Entity bei bidirektionalen Beziehungen Typ Default Class Attributtyp CascadeType[] FetchType EAGER Boolean true String falls keine Kaskadierung für die Beziehung Beziehung definiert wurde ist ein expliziter expliziter Aufruf von persist() notwendig © 2010 >> Stephan Metzler >> V 4.0 >> Seite 78 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen Aufgabe ► Primärschlüssel der Relation selbst erzeugen - Annotation @OneToOne kennzeichnet Address als 1-zu-1-Beziehung - beide in Beziehung stehende Objekte haben immer denselben Primärschlüssel - Annotation @PrimaryKeyJoinColumn - als Unidirektionale 1-zu-1-Beziehung mit gemeinsamem PK @Enity public class Person implements Serializable { @Id @GeneratedValue private Long id; @OneToOne @PrimaryKeyJoinColumn private Address address; @Enity public class Address implements Serializable { @Id private Long id; @Test public void createPersonWithAddress() { persist(p) erzeugt einen Primärschlüssel für die Person Person p = new Person(); id für die Entity Address muss selbst gesetzt werden p.setName("Name"); bank.createPerson(p); bank.createAddress(new Address(bank.getPerson(p.getName()).getId(),"Strasse", "Ort")); assertEquals("Strasse", bank.getPerson(p.getName()).getAddress().getStreet()); assertEquals("Ort", bank.getPerson(p.getName()).getAddress().getCity()); } Aufgabe ► bibi-direktionale 1:1 Beziehung - Address kann Person referenzieren - Address.person mit @OneToOne annotiert - Attribut mappedBy definiert die führende Entity ► auch die "owing" Seite der Beziehung @Enity public class Person implements Serializable { @Id @GeneratedValue private Long id; @OneToOne @PrimaryKeyJoinColumn private Address address; @Entity public class Address implements Serializable { @Id private Long id; @OneToOne(mappedBy = "address") private Person person; @Test public void bidirektionalePersonAddressBeziehung() { Person p = new Person(); p.setName("Name"); bank.createPerson(p); bank.createAddress(new Address(bank.getPerson(p.getName()).getId(),"Strasse", "Ort")); assertEquals("Name", bank.getAddress("Strasse","Ort").getPerson().getName()); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 79 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12.4 @OneToMany - jedes Konto gehört einer Person - sonst existiert es nicht ► Komposition - eine Person hat mehrere Konten - eine Person kann auch kein Konto haben Annotation Parameter targetEntity cascade fetch mappedBy orphanRemoval @OneToMany ► M F Beschreibung Entitätsklasse Angabe der Kaskadierungsoperationen definiert Ladeverhalten des Attributs definiert Attribut der führenden Entity löscht die in Beziehung stehenden Entities mit Typ Default Class Attributtyp CascadeType[] FetchType LAZY String boolean false @OneToMany(cascade = CascadeType.PERSIST, fetch=FetchType.EAGER) private List<Account> accounts; Komposition vs. Aggregation wiki Die Komposition (composite (composite aggregation oder composition) composition) als Sonderfall der Aggregation beschreibt die Beziehung zwischen einem Ganzen und seinen Teilen. Teilen. Der Unterschied zur Aggregation ist im Kern, dass die Existenz des TeilTeil-Objektes durch die des übergeordneten Objektes bedingt ist. Ein Teil kann immer nur genau einem Ganzen zugeordnet sein. So kann z. B. ein Raum immer nur zu genau einem Gebäude gehören, gehören, nie zu keinem oder mehreren. - verstärkt die Bindung einer Assoziation - unterschieden durch die grafischen Darstellung - das das Ende, das mit dem Ganzen verbunden ist - Komposition - ausgefüllte Raute - Aggregation - nicht ausgefüllte Raute © 2010 >> Stephan Metzler >> V 4.0 >> Seite 80 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12.4.1 @OneToManay Parameter - cascade - Weitergeben der Persistenzfunktionalität an den in Beziehung stehenden Entities - fetch - Laden der in Beziehung stehenden Entities cascade Parameter value Beschreibung Typ Default Cascade-Stategie CascadeType[] kein Durchreichen CascadeType Parameter Beschreibung alle Persistenzfunktionen des Entitymangers werden weitergereicht ALL reicht Entitymanager.remove an die in Beziehung stehende Entity weiter REMOVE reicht Entitymanager.persist an die in Beziehung stehende Entity weiter PERSIST REFRESH reicht Entitymanager.refresh an die in Beziehung stehende Entity weiter reicht Entitymanager.merge an die in Beziehung stehende Entity weiter MERGE org.hibernate.annotations.CacadeType definiert die Cascadierung feingranularer fetch Parameter Parameter value Beschreibung Typ Default Fetch-Stategie FetchType LAZY FetchType Parameter Beschreibung alle in Beziehung stehenden Entities werden sofort vollständig geladen EAGER die in Beziehung stehenden Entities werden erst bei Bedarf (nach-) geladen LAZY - Eager Load ► teuer: ressourcen- und zeitintersiv - Daten einer Entität werden sofort vollständig aus der Datenbank gelesen - - in entsprechende Attribute geschrieben alle referenzierten persistenten Objekte werden rekursiv instanziert - sofort und vollständig aus der Datenbank geladen - Lazy Load ► sinnvoll bei grossen Datenmengen - Daten einer Entität werden erst aus der Datenbank geladen wenn ein entsprechender Zugriff darauf - erfolgt gilt auch für die referenzierte Objekte LazyLazy-LoadingLoading-Strategie ist in der der Praxis komplex ► unklare Spez. © 2010 >> Stephan Metzler >> V 4.0 >> Seite 81 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen Aufgabe ► @OneToMany - testen Sie die 1:N Bezehung - zwischen Person und Konto @OneToMany(cascade = CascadeType.PERSIST, fetch=FetchType.EAGER) private List<Account> accounts; @Test public void createPersonWithAccounts() { Person p = new Person(); p.setName("Name"); Account a1 = new Account("123-0", "Privatkonto", 100.0f , "CHF"); Account a2 = new Account("123-1", "Sparkonto", 200.0f , "CHF"); Account a3 = new Account("123-2", "Lohnkonto", 300.0f , "CHF"); List<Account> accounts = new ArrayList<Account>(); accounts.add(a1); accounts.add(a2); accounts.add(a3); p.setAccounts(accounts); bank.createPerson(p); assertEquals(3, bank.getPerson(p.getName()).getAccounts().size()); } - es wird dabei eine Verbindungstabelle erstellt © 2010 >> Stephan Metzler >> V 4.0 >> Seite 82 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12.5 JoinColumn - definiert die Tabellenspalte als Fremdschlüssel der Beziehung Annotation @JoinColumn ► M F Parameter Beschreibung Spaltenname name Typ Default String Attributsname Boolean false Boolean true Boolean true Boolean true updatable definiert eindeutiges Schlüsselfeld kann alternativ über uniqueConstraint auf Tabellenebene deklariert werden erlaubt Null-Werte hat für primitive Java Typen keine Wirkung definiert die Insert-Funktionalität des Persistence Providers für dieses Attribut definiert die Update- Funktionalität des Persistence Providers für dieses Attribut columnDefinition Fragment der SQL Typendefinition String referencedreferencedColumnName Name der Spalte auf die referenziert wird String unique nullable insertable referenzierte Spalte PK der referenzierten Tabelle Aufgabe ► @OneToMany mit JoinColumn - referencedColumnName definiert Name des referenzierten Feldes - testen Sie 1:N Beziehung mit einer JoinColumn testen Sie ohne cascading und mit FetchType=LAZY @OneToMany @JoinColumn(name="p_fk", referencedColumnName="id", nullable=false ) private List<Account> accounts; public void createPerson(Person person) { manager.persist(person); List<Account> accounts = person.getAccounts(); for (Account account : accounts) manager.persist(account); } public Person getPerson(String name) { Person person = (Person)manager.createNamedQuery("... person.getAccounts(); return person; } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 83 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12.6 @ManyToOne - gleiche Konstelation - andere Sichtweise ► Account - Person Annotation Parameter targetEntity cascade fetch optional @ManyToOne ► M F Beschreibung Entitätsklasse Angabe der Kaskadierungsoperationen definiert Ladeverhalten des Attributs erlaubt Null-Werte gibt an ob die Assoziation belegt sein muss hat für primitive Java Typen keine Wirkung Typ Default Class Typ des Attributs CascadeType[] FetchType EAGER Boolean true - Account hat ein person Attribut @Entity public class Account implements Serializable { @Id @GeneratedValue private Long id; @ManyToOne(cascade=CascadeType.ALL ,fetch= FetchType.EAGER) private Person person; Besitzer der Assoziation - 1:N Beziehung durch Fremdschlüssel gemapped - N-Seite ist immer Besitzer der Assoziation ► Konto ist N-Seite @Entity public class Person implements Serializable { @Id @GeneratedValue private Long id; @OneToMany(mappedBy="person", cascade = CascadeType.ALL) private List<Account> accounts; - die Refernezielle Integrität muss manuel gesetzt werden @Entity public class Person implements Serializable { public void addAccount(Account account){ this.accounts.add(account); account.setPerson(this); } public void removeAccount(Account account){ this.accounts.remove(account); account.setPerson(null); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 84 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12.7 Verbindungstabelle - kann auf alle Beziehungstypen angewendet werden - durch die Annotation @JoinTable - @JoinColumns definiert Tabellen- und Feldnamen - definiert Kompatibiltät zu bestehendem Schema - ermöglicht Nachvollziehbarkeit - durch zusätzliche Spalten in der Jointable ► z.B. Timestamp Annotation @JoinTable ► M F Parameter Beschreibung Name der Relationstabelle name Tabellenschema schema Tabellenkatalog catalog PK Spalten der führenden Entity joinColumns inverseJoinColumn PK Spalten der nichtführenden Entity uniqueConstraint Unique-Constraints, die auf der Relationstabelle definiert werden sollen Typ String String String JoinColumn[] JoinColumn[] UniqueConstraint[] Default DB Schema DB Katalog Aufgabe ► Beziehungstabelle Beziehungstabelle - testen Sie die Person – Konto Beziehung - definieren Sie eine JoinTable ► T_PERSON_KONTO @Entity public class Account implements Serializable { @ManyToOne(cascade=CascadeType.ALL ,fetch= FetchType.EAGER) @JoinTable( name = "T_PERSON_KONTO", joinColumns = { @JoinColumn( name = "Konto_PK") }, inverseJoinColumns = { @JoinColumn(name = "Person_PK") }) private Person person; - testen Sie bi-direktional assertEquals(3, bank.getPerson(p.getName()).getAccounts().size()); assertEquals("123-0", bank.getAccount("Privatkonto").getNr()); assertEquals("Name", bank.getAccount("Sparkonto").getPerson().getName()); © 2010 >> Stephan Metzler >> V 4.0 >> Seite 85 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12.8 @ManyToMany - werden immer durch eine Verbindungstabelle abgebildet Annotation Parameter targetEntity cascade fetch mappedBy @ManyToMany ► M F Beschreibung Typ Entitätsklasse Angabe der Kaskadierungsoperationen definiert Ladeverhalten des Attributs definiert Attribut der führenden Entity Class Typ des Attributs CascadeType[] FetchType LAZY String - am Beispiel Verwalter – Konto @Entity public class Trustee implements Serializable { @Id @GeneratedValue private Long id; @ManyToMany(mappedBy = "trustees") private List<Account> accounts; @Entity public class Account implements Serializable { @Id @GeneratedValue private Long id; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List<Trustee> trustees; Default Auzfgabe ► Verwalter – Konto - testen Sie die entsprechende @ManyToMany Beziehung - die JoinTable wird per Default aus den Namen der beiden Tabellen zusammengesetzt - beidseitig müssen die Funktionalitäten zur referenziellen Integrität ermöglicht werden public void addAccount(Account account) { this.accounts.add(account); account.getTrustees().add(this); } public void removeAccount(Account account) { this.accounts.remove(account); account.getTrustees().remove(this); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 86 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Assoziationen 12.9 Transitive Persistenz - bezeichnet alle Objekte, die von einem persistenten Objekt erreichbar sind - durch Kaskadieren von Persistenzoperationen - erlaubt die Weitergabe von Entity-Operationen ► persist(), merge(), delete() - durch die Annotation ► CascadeType - bei allen Beziehungen ► @OneToOne, @OneToMany, @ManyToOne und @ManyToMany @ManyToMany(cascade = CascadeType.ALL) - A.persist() persistiert auch alle an A hängenden Objekte B - weitere CascadeTypes überschreiben die CascadeTypes der Java Persistence API - Annotation @org.hibernate.annotations.Cascade - definiert CascadeType mit Annotation @org.hibernate.annotations.CascadeType @org.hibernate.annotations.Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.REPLICATE }) CascadeTypes ► JPA vs. Hibernate CascadeTypes JPA Hibernate PERSIST PERSIST MERGE DETACH MERGE REMOVE REMOVE REFRESH REFRESH DELETE DELETE ALL SAVE_UPDATE REPLICATE DELETE_ORPHAN LOCK EVICT ALL Beschreibung Übergang ► managed Entity commit() oder flush() persistiert Objekt in der Datensource Übergang ► detached Entity zu managed Entity Übergang ► managed Entity zu detached Entity Übergang ► removed Entity commit() oder flush() löscht Objekt in der Datensource Synchronisiert die Entity Instanz mit der Datensource. Änderungen innerhalb der Entity werden dabei überschrieben entspricht javax.persistence.REMOVE entspricht casade = { PERSIST, MERGE, DETACH, REMOVE, REFRESH } save(Object entity) oder update(Object entity) wird durchgereicht Objekt unter Verwendung der existierenden Id in der Datenbank persistiert Objekte, die nicht mehr referenziert werden, werden gelöscht LockMode für pessimistisches Locking wird durchgereicht Objekt wird aus der Session gelöscht Beinhaltet … und SAVE_UPDATE, DELETE, EVICT und LOCK. © 2010 >> Stephan Metzler >> V 4.0 >> Seite 87 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Vererbung 13 Vererbung - JPA definiert drei verschiedene Vererbungsstrategien SINGLE_TABLE - eine Tabelle als flache Hierarchie - Unterscheidungsmerkmal ist eine Diskriminator-Spalte - Polymorphe Abfragen sind möglich TABLE_PER_CLASS ► optional - eine Tabelle pro konkreter Entity-Klasse - jede Tabelle enthält ALLE Attribute ► auch der Superclass - keine polymorphen Abfragen möglich ► QL UNION als Behelf JOINED - eine Tabelle pro Klasse ►auch abstakte - eine Tabelle pro Klasse einer Vererbungshierarchie - polymorphe Abfragen sind möglich ► nicht performant 13.1 Single_Table - einfachste Möglichkeit ► Defaultstrategie - Klassen werden in einer einzigen Tabelle abgebildet - als flache Hirarchie - @Inheritance bestimmt Vererbungsstrategie - @DiscriminatorValue definiert Tabelleneintrag - @DiscriminatorColumn definiert Typ und Name der Discriminatorspalte - Typ definiert als Dtype pder String - Name beschreibt Vererbung, z.B: Sparkonto oder Privatkonto Annotation @Inheritance ► C Parameter Beschreibung Vererbungsstrategie strategy Typ Default InheritanceType © 2010 >> Stephan Metzler >> V 4.0 >> Seite 88 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Vererbung Annotations für die Vererbung Annotation @DiscriminatorValue ► C Parameter Beschreibung Wert der Discriminatorspalte value Typ Annotation @DiscriminatorColumn ► C Parameter Beschreibung Spaltenname name Typ Default String DTYPE Default String discriminatorType Spaltentyp [STRING, CHAR, INTEGER] DiskriminatorTyp STRING columnDefinition Fragment der SQL Typendefinition String entsprechend referenzierte Spalte lenght Spaltenbreite nur für STRING int 31 - MappedSuperclass definiert ein abstraktes Objekt in einer Vererbungsstrategie - ohne eigene Tabelle Annotation @MappedSuperclass ► C Parameter Beschreibung Typ Default Aufgabe ► Single_Table - testen Sie die Vererbungsstategie Single_Table - abstrakte Klasse Konto bestimmt Vererbungsstrategie mit InheritanceType konkrete Klassen definieren Discriminatorvalue @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public abstract class Account implements Serializable { @Entity @DiscriminatorValue(value = "Sparkonto") public class Deposit extends Account { @Entity @DiscriminatorValue(value = "Privat") public class Personal extends Account { @Entity @DiscriminatorValue(value = "Euro") public class Euro extends Account { © 2010 >> Stephan Metzler >> V 4.0 >> Seite 89 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Vererbung 13.2 Table_Per_Class - jede konkrete Klasse in einer eigenen Tabelle - Tabellen eindeutig den Entities zugeordnet Die Persistenzprovider sind gemäss JPA Spezifikation nicht verpflichtet, die TABLE_PER_CLASSTABLE_PER_CLASS-Strategie bereitzustellen. Aufgabe ► Table_Per_Class - testen Sie die Vererbungsstategie Table_Per_Class - abstrakte Klasse bestimmt Vererbungsstrategie Tabellen für konkrete Entitäten erhalten auch die Attribute der geerbten Klasse @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class Account implements Serializable { @Id @GeneratedValue(strategy = GenerationType.TABLE) private Long id; @Entity public class Deposit extends Account { @Entity public class Personal extends Account { @Entity public class Euro extends Account { - JBoss verlangt TABLE-Generation-Stategy bei "Mapped Tables" © 2010 >> Stephan Metzler >> V 4.0 >> Seite 90 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Vererbung 13.3 Joined - jede abstrakte und jede konkrete Klasse hat eigene Tabelle - jede Tabelle hat einen Primärschlüssel - Primärschlüssel ist auch Fremdschlüssel zur Superklasse - optionale Definition möglich für Implementierungen anderer Persistenzprovider Aufgabe ► Joined - testen Sie die Vererbungsstategie Joined - abstrakte Klasse bestimmt Vererbungsstrategie alle Objekt der Vererbungsstategie werden in eigenen Tabellen gemapped - abstrakte und konkrete Entities @Entity @Inheritance(strategy = InheritanceType.JOINED) public abstract class Account implements Serializable { @Id @GeneratedValue(strategy = GenerationType.TABLE) private Long id; @Entity public class Deposit extends Account { @Entity public class Personal extends Account { @Entity public class Euro extends Account { © 2010 >> Stephan Metzler >> V 4.0 >> Seite 91 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Vererbung Zusammenfassung ► Vererbungsstrategien Joined Table_Per_Class Single_Table Vererbungsstrategie Strategie Begründung Vorteil Nachteil Vorteil Nachteil Vorteil Nachteil gute Performance, da polymorphe Abfragen nur immer eine Tabelle betreffen geeignet für wenig Attribute polymorphe Abfragen grosse Vererbungshierarchien erzeugen sehr grosse Tabellen redundante Spalten schlechte Datenintegrität da Felder der abgeleiteten Klassen NULL Werte haben geeignet für Vererbungshierarchien ohne polymorphe Abfragen und Beziehungen Abfragen auf konkrete Klassen sehr einfach und performant Tabellenstruktur ist abhängig von den Superklassen polymorphe Abfragen nicht optimal unterstützt Datenbankintegrität wird nicht verletzt Attribute in den Subklassen haben keine NULL Werte polymorphe Abfragen und Assoziationen sind möglich komplexe Abfragen schlechte Performance Abfrage auf eine konkrete Klasse benötigt Inner-Joins Vererbungsstategieren in der Praxis Vererbungsstategieren Eigeschaft SINGLE_TABLE wenig wenig Attribute viele Attribute preformant polymorphe Queries TABLE_PER_CLASS JOINED () nur konkrete Querries komplexe Hirarchie Querries nur auf eine Tabelle Union Select Inner / Outer Joins - Joined ► für Abfragen über alle Kontos sind Outer Joins notwendig SELECT a.name, a.saldo, a.currency, p.debitInterest, d.interest FROM Account AS a LEFT OUTER JOIN Personal AS p ON a.id = p.id LEFT OUTER JOIN Deposit AS d ON a.id = d.id WHERE ... © 2010 >> Stephan Metzler >> V 4.0 >> Seite 92 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Collections 14 Collections - Assoziationen zwischen Entities werden als Collections umgesetzt - auch Verwendung von Value Types - - repräsentieren keine eigenständigen Entities innerhalb der Datenbank ► z.B. Liste von Strings Collections als Attribute von persistenten Klassen - durch Deklaration des Typs als Interface Folgende Interfaces werden unterstützt: - java.util.Set / java.util.SortedSet java.util.Collection java.util.List java.util.Map / java.util.SortedMap selbst definierte Interfaces durch org.hibernate.usertype.UserCollectionType Die Verwendung von Collections in persistenten Klassen erlaubt nur die unterstützten Interfaces. Interfaces. folgender Code wirft eine LaufzeitLaufzeit-Exception Verwalter v = bank.getVerwalter(1L); Set kontos = v.getKontos(); // ok HashSet my_kontos = (HashSet) v.getKontos(); // RuntimeException - Hibernate als Persistenzprovider ersetzt HashSet während persist durch eigene Implementierung - dabei werden durch Entity referenzierte Collection-Instanzvariablen persistiert und referenzlose Collection-Instanzvariablen werden gelöscht - daher ► hascode und equals sinnvoll überschreiben - zwei Entities dürfen nicht auf gleiche Collection-Instanz verweisen - Hibernate unterscheidet nicht zwischen einer Null-Referenz auf eine Collection und einer leeren Collection © 2010 >> Stephan Metzler >> V 4.0 >> Seite 93 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Collections 14.1 Collections mit Index - indexierte Collections ► z. B. List, Map oder Arrays - erlauben Zugriff über Index - definieren Indexspalte ► bzw. ein Key bei Maps - enthält den Index der Collection - 14.2 List und Array erlauben nur Integer Map erlaubt beliebiger Basistyp Coolection von Basistypen - @ElemetCollection erlaubt eine Collection von Basistypen ► z.B. String Annotation @ElementCollection ► M F Parameter Beschreibung Ladestrategie der Collection fetch referenzierte Klasse targetClass Typ Default FetchType java.lang.Class LAZY Klasse @Entity public class Euro extends Account implements Serializable{ @ElementCollection private Set<String> coupons = new HashSet<String>(); © 2010 >> Stephan Metzler >> V 4.0 >> Seite 94 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15 Datenbankabfragen mittels Abfragen Entities in einer Datenbank finden - JPQL ► Java Persistence Query Language - mit dem Query Interface - zentrale Schnittstelle - DML ► INSERT / DELETE / UPDATE - DRL ► SELECT - Parametrisierung der Query Iteration des Resultset Flushing- / Lockingparameter - HQL ► Hibernate Query Language - starke, objektorientierte Abfragesprache - Criteria API - objektorientierte Abfragen - durch Aufruf einer normalen API formuliert - Native SQL - Abfragen per ANSI SQL formuliert 15.1 Query Interface - zentrale Schnittstelle zur Ausführung von Abfragen - immer wenn Primärschlüssel einer Entity nicht bekannt ist - bei PK ► EntityManager.find() oder EntityManager.getReference() - Suchkriterien zum Finden der Entities - Query-Instanz wird mit Hilfe des EntityManager erzeugt - String-Parameter muss eine gültige JPQL-Abfrage definieren - NativeQuery( ) definiert einen native SQL String ► datenbankspezifisch - Datenbankunabhängigkeit geht verloren public List<Konto> findAccountPersonAddress(String konto, String name, String city) { Query query = manager.createQuery("SELECT k FROM Konto k " + "WHERE k.name LIKE :konto AND k.person.name LIKE :name " + "AND k.person.address.city LIKE :city"); query.setParameter("konto", konto); query.setParameter("name", name); query.setParameter("city", city); return query.getResultList(); } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 95 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen Methoden des Query Interface QueryInterface ► Ausschnitt Methode Beschreibung List getResultList( getResultList( ) Object getSingleResult( getSingleResult( ) int executeUpdate( executeUpdate( ) Query setMaxResults() setMaxResults() Query setFirstResults() Query setHint() Query setParameter() Query setFlushMode() Das Ergebnis wird als Liste zurückgegeben, das heisst, das Resultat der Abfrage befindet sich komplett im Speicher Ist von vornherein bekannt, dass eine Abfrage nur ein einziges Objekt zurück liefert, kann diese Methode verwendet werden, um den Umweg über die Liste zu sparen Ermöglicht UPDATE und DELETE Anweisungen, die sich auf eine ganze Reihe von Entity Beans auswirken könnnen. erlaubt ausschnittweises oder seitenweises Eingrenzen der Ergebnismenge setzen herstellerspezifischer Parameter, z.B. org.hibernate.timeout setzt die Parameter einer dynamischen Query setzt den Synchronisationsmodus AUTO synchronisiert Persistenzkontext und DB vor der Abfrage COMMIT Persistenzkontext synchronisiert erst bei COMMIT 15.2 Ausführen von Abfragen Query Interface liefert: - einfache Instanzen der entsprechenden Wrapperklassen ► Integer, Long, etc. - Object Array List<Konto> kontos = query.getResultList(); Vector<Konto> inhaberKontos = new Vector<Kontos>(); for (Object o : kontos) { inhaberKontos.add((Konto) o); } - auch als benutzerdefinierter Arrays sinnvoll - InhaberKonto @Entity(name = "Person") @SqlResultSetMapping(name = "PersonWithMultipleAccounts", entities = { @EntityResult(entityClass = entity.Person.class, fields = { @FieldResult(name = "name", column = "name") }) }) public class Person implements Serializable { © 2010 >> Stephan Metzler >> V 4.0 >> Seite 96 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15.3 Eingrenzung der Abfrage - setMaxResults(int maxResults) grenzt die Ergebnismenge ein - setFirstResult(int firstResult) setzt einen Zeiger in der Ergebnismenge - Listenweise Ausgabe der Elemente public List<Konto> findAccountPersonAddress(String konto, String name, String city, int offset, int range) { ... query.setFirstResult(offset).setMaxResults(range); 15.4 dynamische Abfragen - benannte Parameter public List<Konto> findAccountPersonAddress(String konto, String name, String city) { Query query = manager.createQuery("SELECT k FROM Konto k " + "WHERE k.name LIKE :konto AND k.person.name LIKE :name " + "AND k.person.address.city LIKE :city"); query.setParameter("konto", konto); query.setParameter("name", name); query.setParameter("city", city); © 2010 >> Stephan Metzler >> V 4.0 >> Seite 97 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15.5 NamedQuery - widerverwendbar - für die Entity definiert - Definition per Metadaten - per Annotation - per XML ► orm.xml - als JPQL auch als Native SQL @Entity @NamedQueries({ @NamedQuery(name = "Person.findAll", query = "from Person p"), @NamedQuery(name = "Person.findByName", query = "from Person p where p.name:=name") }) @SqlResultSetMapping(name = "PersonWithMultipleAccounts", entities = { @EntityResult(entityClass = entity.Person.class, fields = { @FieldResult(name = "name", column = "name") }), @EntityResult(entityClass = entity.Konto.class, fields = { @FieldResult(name = "name", column = "name") }) }) public class Person implements Serializable { .. } Abfragen Abfragen mit NamedQueries NamedQueries - durch die Fassade - parametrierbar public List<Person> findPersonByName(String name) { Query query = manager.createNamedQuery("Person.findByName"); query.setParameter("name", name); List<Person> persons = query.getResultList(); return persons; } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 98 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15.6 JPQL Java Persistence Query Language - Abfragesprache - nicht case sensitive - aber ► Javaklassen und Properties entsprechend korrekt angeben - objektorientiert - Abfragen von Objekten über deren Vererbungsbeziehung FROM Person - JPQL ► Abfrage der Entities vom Typ Person oder einem Subtyp - SQL ► Abfrage der Daten aus der Tabelle Person 15.7 FROM - Abfrage der Entity-Klasse from entity.Person from Person // Hibernate-Mappings Attribute auto-import = true (DEFAULT) from Person as p from Person p // mit Alias from Person, Konto // kartesisches Produkt © 2010 >> Stephan Metzler >> V 4.0 >> Seite 99 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15.8 WHERE - Einschränkung der Ergebnismenge from Person as p where p.name = 'Name' from Person where name = 'Name' from Person as p where p.name like '%Name%' Formulierung von Bedingungen - praktisch alle SQL bekannten Ausdrücke Bedingungen Ausdruck Beschreibung and, and, or, not +, -, *, / =, >=, <=, <>, !=, like () is null, is not null in, not in, between, is empty, is not empty, member of, not member of case ... when ... then ... else ... end, case when ... then ... else ... end ||, concat(..., ...) current_date(), current_time(), current_timestamp(), second(), minute(), hour(), day() day(), month(), year() substring(), trim(), lower(), upper(), length(), locate() abs(), sqrt(), bit_length(), mod() mod() str() cast(), extract() size(), minelement(), maxelement(), minindex(), maxindex() sign(), rtrim(), sin() logische Operatoren zur Verknüpfung von Ausdrücken mathematische Operatoren Vergleichsoperatoren Klammern zur Gruppierung von Ausdrücken Vergleiche auf Null Ausdrücke zum Umgang mit Mengen und Bereichen (Collections etc.) Bedingungen mit Alternativen String Verknüpfungen Verwendung von Zeit und Datum Verwendung von Strings sonstige mathematische Operatoren Umwandlung in einen String Casts zur Umwandlung in HQL-Datentypen sonstige Ausdrücke zum Umgang mit Collections sonstige SQL-Funktionen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 100 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen Beispiele: from Person p where p.kontos.size > 3 // mit mehr als drei Konten from Person p where p.name between 'A' and 'M' from Person p where p.name in ('Markus', 'Martin') from Konto k where k.name like '%konto%' 15.9 ORDER BY - Sortierung der Ergebnismenge - nur über die aktuelle Klasse (Datenbank Tabelle) from Person order by name from Person order by name asc, konto.name desc © 2010 >> Stephan Metzler >> V 4.0 >> Seite 101 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15.10 Verbundoperationen - liefern Kombinationen der beteiligten Entities - inner join / join ► 1:1-Zuordnung. Elemente ohne Zuordnung sind ausgeschlossen - left outer join / left join ►1:1-Zuordnung. inklusive Elemente ohne Zuordnung der linken Tabelle - right outer join / right join ► inklusive Elemente ohne Zuordnung der rechten Tabelle - full join ► kartesisches Produkt select p, konto // alle Personen mit Konten from Person p inner join p.kontos konto select p, k from Person p inner join p.kontos k with k.name like '%konto%' 15.11 FETCH Fetch Strategien durch die Abfrage definiert ► analog LAZY / EAGER - Fetch -Joins - erlaubt Abfragen von Beziehungen und Collections inklusive der 'Parent Objects' - überschreibt outer-join und lazy Deklaration für Beziehungen und Collectionen - Einschränkungen von Fetch-Joins - Ergebnismenge kann nicht iteriert werden - with - Konstrukt nicht geeignet - setMaxResults() / setFirstResult() kann nicht verwendet werden - Duplikate der Parents sind möglich from Verwalter v left join fetch v.konten // mit fetch Strategie © 2010 >> Stephan Metzler >> V 4.0 >> Seite 102 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15.12 SELECT - definiert Ergebnismenge der Objekte und Attribute select k from Person p inner join p.konten k // Instanzen der FROM Entities // also Konto-Instanzen select p, k from Person p inner join p.konten k // Liste von Object[] // Object[0] ist Person Object // Object[1] ist Konto Object select p, k.name from Person p inner join p.konten k // Liste von Object[] // Object[0] ist Person Object // Object[1] ist String Object select new list(i, k) from Inhaber i inner join i.konten k // List als Ergebnistyp select new InhaberKonto(i, k) // typisiertes Java Object from Inhaber i // InhaberKonto als Ergebnis inner join i.konten k // (selbst definierte Javaklasse) © 2010 >> Stephan Metzler >> V 4.0 >> Seite 103 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen benutzerdefinierte Eeignsmenege select new list(p, k) from Person p inner join p.konten k // List als Ergebnistyp select new InhaberKonto(p, k) // typisiertes Java Object from Person p // InhaberKonto als Ergebnis inner join p.konten k // (selbst definierte Javaklasse) 15.13 Aggregat-Funktionen - zur Konsolidierung oder Verdichtung der Ergebnismenge - distributive Funktionen - sum( ), min( ), max( ), count(*), count( ), count(distinct ...), count(all ...) - algebraische Funktionen - avg( ) select count(*) from Person // Anzahl aller Personen select count(distinct p.name) from Person p // Anzahl aller eindeutiger Namen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 104 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15.14 GROUP BY - Gruppieren von Aggregat-Funktionen select t.name, count(k) from Konto k inner join k.trustee t group by t.name // Liste aller Verwalter // mit Anzahl Konten 15.15 Polymorphe Abfragen - SQL kennt das Konzept der Vererbung nicht - JPQL unterstüzt polymorphe Abfragen - liefert Ergebnismenge von Entity-Instanzen einer gemeinsamen Vererbungshierarchie from Konto // liefert auch // Instanzen von Subklassen from java.lang.Object // alle persistenten Objekte © 2010 >> Stephan Metzler >> V 4.0 >> Seite 105 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datenbankabfragen 15.16 Subqueries - falls die darunterliegende Datenbank Subqueries verwendet from Konto kavg where kavg.saldo > ( select avg(k.size) from Konto k ) // Konten die mehr Saldo als // das Durchschnittskonto haben from Konto k where not (k.nr, k.name) in ( select pk.saldo from Personal pk ) // mit Wertemenge > 1 © 2010 >> Stephan Metzler >> V 4.0 >> Seite 106 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datentypen 16 Datentypen - Datenbankzugriffe resultieren in Performance-Problemen - geeignete Fetching-Strategie wählen - geeigneter Typ wählen - Fetching-Strategy bei Attributen @Basic(fetch = FetchType.LAZY) private Object grosseDatenMenge; - Fetching-Strategy bei Beziehungen @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Address address; - Fetch Join Syntax from [left [outer]] / [inner] join fetch association 16.1 Fetching-Strategien JPA Spezifikation definiert zwei Fetching-Strategien: - Lazy Loading - Daten erst laden wenn ein Zugriff auf das Attribut oder das Objekt erfolgt - Persistence Provider ist nicht verpflichtet Lazy Loading zu unterstützen - Umfang einer Umsetzung von Lazy Loading ungenau definiert - Eager Loading - Daten sofort vollständig laden JPA unterstützt Lazy Loading Loading - Entity muss vom EntityManager verwaltet werden - Zugriff auf nicht geladenes Attribut einer detached Entity wirft Exception Ladestrategien für Attribute Annotation @Basic ► M F Parameter Beschreibung definiert Ladeverhalten des Attribut fetch erlaubt Null-Werte, hat für primitive Java Typen keine Wirkung optional Typ Default FetchType EAGER Boolean true © 2010 >> Stephan Metzler >> V 4.0 >> Seite 107 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datentypen Zusammenfassung ► FetchingFetching-Strategien Fetching Annotation @Basic(fetch = FetchType.EAGER / LAZY) @OneToOne(fetch = FetchType.EAGER / LAZY) @ManyToOne(fetch = FetchType.EAGER / LAZY) @OneToMany(fetch = FetchType.EAGER / LAZY) @ManyToMany(fetch = FetchType.EAGER / LAZY) Defaultwert FetchType.EAGER FetchType.EAGER FetchType.EAGER FetchType.LAZY FetchType.LAZY JPQL Fetch Joins - Spezifikation definiert für JPQL-Abfragen Fetch Joins - Beziehungen zwischen Entities werden bei der Ausführung der Abfrage geladen - als Inner Join implementiert - Loading Strategie (EAGER / LAZY) anwendbar - Hibernate bietet zusätzliche Optionen - Batch-Fetching - Subselect-Fetching 16.2 grosse Objekte - umfangreiche Daten (Streams) werden in spezielle Datentypen abgelegt - meistens generische Objekte oder Strings - @Lob deklariert Attribut als Large OBject - Datenbank ist verantwortlich für die Abbildung ► MySQL z.B. als BLOB BinaryLargeObject Annotation @Lob ► M F Parameter Beschreibung Typ Default - @Lob wird oft im Zusammenhang mit @Basic verwendet - um LazyLoading für Large Objects zu definieren. @Lob @Basic(fetch = FetchType.LAZY) private Object grosseDatenMenge; © 2010 >> Stephan Metzler >> V 4.0 >> Seite 108 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datentypen 16.3 Datums- und Zeitwerte - Datums- und Zeitwerte sind für die Speicherung in der Datenbank nicht vordefiniert - java.util.Calender - java.util.Date - @Temporal definiert Datenbankrepräsentation - DATE entspricht java.sql.Date - TIME entspricht java.sql.Time - TIMESTAMP entspricht java.sql.Timestamp Annotation @Temporal ► M F Parameter Beschreibung TemporalType definiert Speichertyp @Temporal(TemporalType.DATE) private java.sql.Date startDatum; Typ Default DATE TIME TIMESTAMP TIMESTAMP 16.4 Aufzählungen - Java SE 5.0 kennt Aufzählungstyp ENUM - @Enumerated deklariert Aufzählungstyp und definiert Art der Persistierung - ORDINAL : Wert wird als Zahl beginnend mit 0 gespeichert - STRING : Wert wird als String gespeichert Annotation @Enumerated ► M F Parameter Beschreibung value definiert Art der Persistierung ORDINAL oder STRING Typ Default EnumType Beispiel ► Kontotyp als Aufzählungstyp public enum KontoTyp { PRIVATKONTO, SPARKONTO, ANLEGEKONTO } @Enumerated(EnumType.ORDINAL) private KontoTyp kontoTyp; © 2010 >> Stephan Metzler >> V 4.0 >> Seite 109 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Datentypen F Transaktionen Lerninhalte Eigenschaften Steuerung Management Annotationen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 110 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement 17 Transaktionsmanagement wiki Als Transaktion (von lat. trans „über“, actio zu agere „(durch)führen“) bezeichnet man in der Informatik eine Folge von Operationen, die als eine logische Einheit betrachtet werden. Insbesondere wird für Transaktionen Transaktionen gefordert, dass sie entweder vollständig oder überhaupt nicht ausgeführt werden (Atomarität). Atomarität). Transaktionen werden von Transaktionssystemen verarbeitet; diese erzeugen dabei aus mehreren Transaktionen eine Historie. Transaktionen kommen meist bei Datenbanksystemen zum Einsatz. 17.1 - Transaktion logisch zusammenhängende Folge von Operationen einer Datenbank wird von einem konsistenten in einen weiteren konsistenten Zustand überführt kleinster, unteilbar abzuarbeitender Prozess einer Anwendung werden vollständig oder gar nicht abgearbeitet 17.1.1 Transaktionskonzepte ACIDACID-Eigenschaften - Atomic (atomar) ► eher Up-Quark, Neutrino oder Myon, etc. - eine Transaktion ist Reihe von "primitiven" unteilbaren Operationen es werden entweder alle Operationen ausgeführt oder gar keine - Consistent (konsistent) - Transaktionen hinterlassen die Datenbank in einem konsistenten Zustand - Isolated (isoliert) - gleichzeitige Transaktionen beeinflussen sich nicht - Durable (dauerhaft) - abgeschlossene Transaktionen sind dauerhaft Transaktionsverhalten - commit - erfolgreiche Beendigung einer Transaktion die Änderungen sind dauerhaft in der Datenbank abgespeichert ► für alle (User) sichtbar - rollback - Transaktionsabbruch führt Änderungen am Datenbestand zum letzten konsistenten Zustand © 2010 >> Stephan Metzler >> V 4.0 >> Seite 111 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement 17.1.2 Lokale und verteilte Transaktionen - lokale Transaktion (local transaction) - nur lokale Daten betroffen - nicht mehrere (Daten)-Ressourcen sind Teil der Transaktion - verteilte Transaktion (distributed transaction) - betreffen mehrere Daten, die auf Verteilten Systemen liegen - müssen in Teiltransaktionen aufgeteilt werden Transaktionsablauf - Business Prozess startet Transaktion 1 - Business Prozess startet Transaktion 2 - Transaktion 1 wird mit commit beendet - Transaktion 2 wird mit commit beendet ► inkonsistente Zustände sind möglich - zweite Commit-Anweisung fällt aus Zwei Phasen Commit 2PC definiert erweitertes Protokoll mit 2 Phasen - Erste Phase - "Prepare-to-Commit" auf allen Knoten - teure Operation - Zweite Phase - sendet ein Commit an die Knoten - billige Operation © 2010 >> Stephan Metzler >> V 4.0 >> Seite 112 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement 17.1.3 Isolationsebenen wiki In der Informatik bezeichnet der Begriff Isolation die Trennung von Transaktionen auf eine Weise, dass eine laufende Transaktion nicht von einer parallel ablaufenden ablaufenden Transaktion durch Änderung der benutzten Daten in einen undefinierten Zustand gebracht werden kann. Die Isolation ist eine der vier ACIDACIDEigenschaften. - komplette Serialisierung der transaktionalen Operationen - sicher, aber teuer - Isolierung ist eine Einschränkung im Vergleich zu idealen ACID Transaktionen - nach ANSI-92 SQL Isolationsebenen Level Beschreibung NONE READ_UNCOMMITTED READ_COMMITTED REPEATABLE_READ SERIALIZABLE keine Transaktion möglich alle Transaktionen sehen die Änderungen von anderen Transaktionen nicht abgeschlossene Transaktionen sind unsichtbar für andere Transaktionen eine Transaktion sieht nur Daten, die vor ihrem Startzeitpunkt vorhanden waren alle Transaktionen verhalten sich, als würden sie hintereinander abgearbeitet 17.1.4 Probleme bei parallelen Datenbankoperationen - Multi-User Applikationen definieren folgende Problem-Szenarien Dirty Read - innerhalb einer Transaktion T1 wird ein Datensatz Z verändert - dieser veränderte Datensatz wird innerhalb einer zweiten Transaktion T2 gelesen - Transaktion T1 mit einem Rollback abgebrochen - die Transaktion T2 arbeitet mit einem ungültigen Wert - Dirty Read dirty read Transaktionsablauf 1 User T1 Daten Z User T2 2 3 UPDATE 10 11 4 5 ROLLBACK 11 SELECT 10 10 SELECT © 2010 >> Stephan Metzler >> V 4.0 >> Seite 113 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement Non Repeatable Read - innerhalb einer Transaktion T1 wird ein Datensatz Z gelesen - die zweite Transaktion T2 ändert diesen Datensatz Z - die Transaktion T2 wird commited - erneutes Lesen von Z durch die Transaktion T1 ergibt einem ungültigen Wert - Non-Repeatable Read nonrepeatable read Transaktionsablauf 1 User T1 Daten Z User T2 2 3 4 SELECT 10 10 5 SELECT 11 11 UPDATE COMMIT 11 Phantom Read - die Transaktion T1 liest die Ergebnismenge der Daten Z (count = 2) - die Transaktion T2 verändert die Anzahl Datensätze mit Insert / Delete - die Transaktion T2 wird committed - erneutes Lesen von Z durch die Transaktion T1 ergibt eine ungültige Ergebnismenge - Phantom Read phantom read Transaktionsablauf User T1 SELECT Daten Z User T2 1 10,11 2 10,11 3 4 5 SELECT 11,11,12 11,11,12 INSERT COMMIT 10,11,12 © 2010 >> Stephan Metzler >> V 4.0 >> Seite 114 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement mögliche mögliche Vorkommen bei Isolationsebenen mögliche Reads Isolationsebene Read Uncommitted Read Committed Repeatable Read Serializable Dirty Read Non Repeatable Read Phantom Read - mit zunehmendem Isolationsgrad - sicherere Transaktion - schlechtere Performance, da mehr Sperren innerhalb der Datenbank kontrollierbar auch durch entsprechende Lock Strategien ► auf DB LOCK {TABLE | TABLES} <table name> [AS <alias>] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [{, <table name> [AS <alias>] {READ [LOCAL] | [LOW_PRIORITY] WRITE}}...] 17.2 Propagation wiki Unter Propagation oder Propagierung (von Lateinisch propagare „ausdehnen“) versteht man im weitesten Sinne eine Ausdehnung. Ausdehnung. Propagations Bezeichnung Verhalten PROPAGATION_MANDATORY erfordert eine laufende Transaktion ► Exception PROPAGATION_NESTED erfordert eine eigenständige Transaktion PROPAGATION_NEVER erlaubt keine offene Transaktion ► Exception PROPAGATION_NOT_SUPPORTED unterbricht eine offene Transaktion PROPAGATION_REQUIRED startet eine neue oder übernimmt eine bestehende Transaktion PROPAGATION_REQUIRES_NEW startet eine neue Transaktion PROPAGATION_SUPPORTS übernimmt eine geöffnete Transaktion © 2010 >> Stephan Metzler >> V 4.0 >> Seite 115 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement - ermöglicht feingranulares Transaktionssverhalten Transaktionspropagation Bezeichnung NotSupported, Supports, Never Required, RequiresNew Mandatory NotSupported Supports, Required, Mandatory RequiresNew, Nested Never aufrufende Methode weiterführende weiterführende Methode 17.3 JTS Java Transaction Service - JTS spezifiziert die Implementierung eines Transaktionsmanagers TransaktionsManager - realisiert die Koordination von Transaktionen - Start, Abbruch und Abschluss Realisierung globaler, verteilter Transaktionen verwaltet die beteiligten Ressourcen einer globalen Transaktion ► RessourceManger - koordiniert Zwei-Phasen-Commit-Protokoll - kooperiert mit anderen Transaktionsmanagern RessourcenManager - kontrolliert transaktionsunterstützende (XA-kompatible) Ressource © 2010 >> Stephan Metzler >> V 4.0 >> Seite 116 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement 17.4 JTA Java Transaction API - JTA spezifiziert die Programmierschnittstelle - für EJB, JDBC, JMS, JTS - Zugriff erfolgt mit der Java Transaction API Schnittstelle - besteht aus mehreren Interfaces - javax.transaction.UserTransaction - Transaktion starten ► begin() - Transaktion abbrechen ► rollback() - Transaktion abschliessen ► commit() - Transaktionsstatus lesen ►getStatus() - Rollback erzwingen ► setRollbackOnly() - Timeout setzen ►setTransactionTimeout(sec) - javax.transaction.TransactionManager - laufender Transaktionscontext holen ►getTransaction() - laufende Transaktion anhalten ►suspend() - Transaktion wieder aufnemen ► resume(T) 17.5 Transaktionshandling wiki Als Konsistenz bezeichnet man bei Datenbanken allgemein die Widerspruchsfreiheit von Daten. Daten. Konsistenz ist eine eine der vier in DatenbankDatenbank-Transaktionen geforderten ACIDACID-Eigenschaften. Eigenschaften. Transaktionen müssen Datenbanken von einem konsistenten in einen anderen konsistenten Zustand überführen. Während der Verarbeitung der Anfrage kann die Konsistenz der Datenbank jedoch jedoch durchaus verletzt sein. - ACID-Prinzipien einghalten ►Konsistenz - EJB-Spezifikation definiert zwei Typen - explizite ► bean-managed transactions - implizite ► container-managed transactions © 2010 >> Stephan Metzler >> V 4.0 >> Seite 117 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement 17.5.1 Bean Managed Transaction steuert Transaktionen explizit ► direkt - durch das JTA Inteface UserTransaction - Transaktionen mit anderen EJBeans - Transaktionen mit Datenbanken über JDBC Deklarativ ► ejb-jar.xml <enterprise-beans> <session> <ejb-name>BankBean</ejb-name> <transaction-type>Bean</transaction-type> <session> <enterprise-beans> Annotiert @TransactionManagement(TransactionManagementType.BEAN) @Stateful public class BankBean implements Bank { ... } Steuerung der Transaktion ► mit UserTransactionUserTransaction-Objekt - als JNDI lookup ic = new InitialContext(); UserTransaction ut = (UserTransaction) ic.lookup("java:comp/env/UserTransaction"); ut.begin(); ... - über SessionContext @Resource SessionContext sc; UserTransaction ut = sc.getUserTransaction(); - über Dependency Injection @TransactionManagement(TransactionManagementType.BEAN) @Stateful public class KontoBean implements Konto { @Resource UserTransaction ut; © 2010 >> Stephan Metzler >> V 4.0 >> Seite 118 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement 17.5.2 Container Managed Transactions - steuert Transaktionen implizit ► indirekt ► durch Kontainer - kein zusätzlicher Code in die Geschäftslogik ► try-catch-Blocks definiert Transaktion - Fehler (catch) führt alle schon durchgeführten Anweisungen zurück ► ROLLBACK - keine verschachtelten Transaktionen möglich CMT für Methoden @TransactionAttribute(TransactionAttributeType.REQUIRED) public void transfereAmount(Konto fromAccount, Konto toAccount, Float amount) { try { withdrawAmount(fromAccount, amount); depositAmount(toAccount, amount); } catch (Exception e) { e.printStackTrace(); } } @TransactionAttribute(TransactionAttributeType.REQUIRED) public void withdrawAmount(Konto k, Float amount) { k.setSaldo(k.getSaldo() - amount); if (k.getSaldo() < 0) sc.setRollbackOnly(); } Annotationen für die Transaktionssteuerung Transaktionssteuerung - auf Bean-Ebene Annotation @TransactionManagement ► C Parameter Beschreibung TransactionManagementType Transaktionsmanagement Konstante Default CONTAINER BEAN CONTAINER - auf Methoden-Ebene Annotation @TransactionAttribute ► M Parameter Beschreibung Beschreibung TransactionAttribute TransactionAttributeType AttributeType Transaktionsattribut Konstante Default REQIRED REQUIRES_NEW MANDATORY SUPPORTS NOT_SUPPORTED NEVER REQUIRED © 2010 >> Stephan Metzler >> V 4.0 >> Seite 119 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement - Transaktions-Attribute - Required - die Bean soll immer in einer Transaktion laufen - RequiresNew - es wird immer eine neue Transaktion gestartet - Supports - die Methode wird zur Transaktion des Aufrufers einbezogen - Mandatory - diese Bean-Methode gehört immer zur Transaktion des aufrufenden Clients - NotSupported - diese Methoden können keine Transaktionen unterstützen oder erzeugen - Never - die Methode darf nicht in eine Transaktion einbezogen werden - nicht alle Transaktions-Attribute lassen sich mit allen Beans nutzen - Tabelle zeigt Kombinationsmöglichkeiten Transaktions-Attribut SLSB SFSB MDB Required RequiresNew Mandatory Supports NotSupported Never 17.6 Application Exception - Unterscheidung von Exceptions - System Exception ► unchecked - - Ausnahme der technischen Infrastruktur Applikation Exception ►checked - Ausnahme der Geschäfslogik - checked ►müssen deklariert / gehandelt werden - Subklassen von java.lang.Exception - unchecked ► müssen nicht deklariert / gehandelt werden - Subklassen von java.lang.RuntimeException Applikation Exception führen nicht automatisch zu einem transaktionalen Rollback - ExceptionKlasse muss mit @ApplicationException annotiert werden Annotation @ApplicationException ► C Parameter rollback rollback Beschreibung Typ Default Rollbackverhalten bei einer Exception Boolean false © 2010 >> Stephan Metzler >> V 4.0 >> Seite 120 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionsmanagement Bespiel ► ApplicationException - unterschreiten der Kreditgrenze soll verhindert werden @ApplicationException(rollback = true) public class SaldoBelowCreditLimitException extends Exception { public SaldoBelowCreditLimitException (String reason) { System.out.println(reason); } } @TransactionAttribute(TransactionAttributeType.REQUIRED) public void transfereAmount(String fromAccount, String toAccount, Float amount) { try { withdrawAmount(fromAccount, amount); depositAmount(toAccount, amount); if (getSaldo(fromAccount) > Konto.creditLimit) throw new SaldoBelowCreditLimitException("Kreditlimite erreicht"); if (getSaldo(toAccount) > Konto.creditLimit) throw new SaldoBelowCreditLimitException("Kreditlimite erreicht"); } catch (Exception e) { e.printStackTrace(); } } Aufgabe ► Kontotransfer als Transaktion - testen Sie das transaktionale Verhalten der EJBs mit einem Kontotrandfere - explicit ► BMT Bean Managed Transaction implezit ► CMT Container Managed Transaction ApplicationException Transaktionsverhalten transfereAmount() depositAmount() withdrawAmount() REQUIRED REQUIRED REQUIRED REQUIRED REQUIRES_NEW REQUIRED SUPPORTS REQUIRED REQUIRED REQUIRED SUPPORTS SUPPORTS NOT_SUPPORTED REQUIRED REQUIRED NOT_SUPPORTED NOT_SUPPORTED NOT_SUPPORTED REQUIRED NEVER NEVER Transaktion © 2010 >> Stephan Metzler >> V 4.0 >> Seite 121 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionen der Persistence Unit 18 Transaktionen der Persistence Unit - verschiedene Anwendungsszenarienfür transaktionale Operationen ► Patterns - basieren auf der Verwendung von - JDBC Connections Java Transaction API (JTA) - optimistischen Locking - beim Schreiben wird geprüft ob sich die Daten verändert haben - implementiert durch die Verwendung von Versionsattributen @Version - pessimistisches Locking - lesender Client sperrt Daten - implementiert durch API die SELECT FOR UPDATE der Datenbank umsetzt - Repeatable-Read-Semantik definiert Caching innerhalb Persistenz-Session - dabei muss jede Datenbankoperation innerhalb einer Transaktion laufen - auch reine Leseoperationen - aktiver Auto-Commit-Modus wird (durch Hibernate) deaktiviert - sollte generell nicht in Verbindung mit Hibernate eingesetzt werden Verwendung von Transaktionen unterscheidet - managed ► innerhalb eines JEE Application Servers - BMT (Bean Managed Transactions) - CMT (Container Managed Transactions) - non-managed ► in einer JSE Anwendung - Spring - Web-Kontainer © 2010 >> Stephan Metzler >> V 4.0 >> Seite 122 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionen der Persistence Unit 18.1 Optimistisches Locking optimistisches Locking bedeutet ► meistens geht alles gut - hohe Performance - gute Skalierbarkeit Praxis ► wenn keine Überschneidungen von Änderungen durch parallele Transaktionen - Auftreten einer Überschneidung wird durch aufwändige, manuelle Korrektur behoben - z.B. durch Versionierung der Datensätze ► Version Pattern / Timestamp in Tabelle - manueller Ansatz nur bei kleinen, trivialen Persistenzlösungen praktikabel - manuelle Überprüfung eines komplexen Objektgraphen nicht einfach oder auch Last Commit Wins ► Verwirrungen seitens der User manuelle Überprüfung mittels Versionsvergleich für jede Entity ► Version Pattern - Versionsattribut der Entities wird automatisch beim Commit hochgezählt 18.2 Versionsprüfung durch Version Number - Entity Manager prüft beim Speichern auf Zustandsänderungen der Daten - durch ein Commit aktualisiert - JPA definiert automatische Versionsüberprüfung durch Version-Attribut - mit @Version annotiertes Attribut darf durch Applikation nicht verändert werden - Attribut wird bei jeder Veränderung hochgezählt Annotation @Version ► M F Parameter Beschreibung Typ Default Beispiel @Version @Column(name="Versionfeld") private int version; das Version Pattern ist durch die JPA Spezifikation implementiert © 2010 >> Stephan Metzler >> V 4.0 >> Seite 123 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionen der Persistence Unit 18.3 Pessimistisches Locking Praxis ► bei häufigen Kollisionen zwischen konkurrierenden Transaktionen - restriktives Vorgehen verlangt - Tabellenzeilen werden explizit gesperrt - konkurrierende Transaktion erhält Fehlermeldung - konkurrierende Transaktion muss warten - verschlechtert Gesamtperformance des Systems aufgrund wartenden Transaktionen LockingLocking-Mechanismus - um Deadlocks innerhalb der Datenbank zu vermeiden - Hibernate nutzt für pessimistisches Locking die Datenbank Funktionalität - Hibernate setzt nie Locks auf Entity-Objekte im Speicher! - Klasse LockMode definiert verschiedene Lock-Modi - es stehen nicht immer alle Modi zur Verfügung (Datenbankabhängig) falls gewünschter Lock-Modus nicht unterstützt wird wählt Hibernate automatisch einen verwandten, verfügbaren Modus LockMode definiert verschiede LockLock-Modus LockMode Parameter NONE READ UPGRADE UPGRADE_NOWAIT WRITE Beschreibung Beschreibung Es wird kein Lock auf Zeilen in der Datenbank gesetzt. Mit diesem Modus wird beim Lesen eines Datensatzes nur auf die Datenbank zugegriffen, wenn sich die entsprechende Entity nicht im Cache befindet. Dieser Lockmodus weist Hibernate an, direkt auf die Datenbank zuzugreifen und eine Versionsüberprüfung der betroffenen Entities durchzuführen. Sinnvoll z. B. bei Verwendung von Detached Entities. Dieser Lockmodus wird von Hibernate automatisch verwendet, wenn als Isolationsebene Repeatable Read oder Serializable ausgewählt wurde. Wird für pessimistisches Locking verwendet. Es wird mit SELECT ... FOR UPDATE ein Lock auf die Tabellenzeilen gesetzt, wenn die Datenbank dieses Feature unterstützt. Verhält sich wie UPGRADE. Durch ein SELECT ... FOR UPDATE NOWAIT, welches in Oracle Datenbanken verfügbar ist, wird die DB angewiesen, nicht darauf zu warten, falls die selektierte Tabellenzeile bereits gelockt ist, sondern eine Locking Exception zu werfen. Ein "interner" Modus, der automatisch von Hibernate verwendet wird, wenn ein Datensatz aktualisiert oder eingefügt wird. Dieser Modus kann nicht explizit durch den User verwendet werden. LockLock-Modi erlauben pessimistisches Locking auf feingranularer feingranularer Ebene © 2010 >> Stephan Metzler >> V 4.0 >> Seite 124 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Transaktionen der Persistence Unit G Idioms Lerninhalte Lerninhalte Design Pattern Idioms © 2010 >> Stephan Metzler >> V 4.0 >> Seite 125 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns 19 Design Patterns wiki Entwurfsmuster (engl. (engl. design patterns) patterns) sind bewährte LösungsLösungs-Schablonen für wiederkehrende Entwurfsprobleme in Softwarearchitektur und Softwareentwicklung. Softwareentwicklung. Sie stellen damit eine wiederverwendbare Vorlage Vorlage zur Problemlösung dar, die in einem bestimmten Zusammenhang einsetzbar ist. In den letzten Jahren hat der Ansatz der Entwurfsmuster auch zunehmendes Interesse im Bereich der MenschMensch-ComputerComputer-Interaktion gefunden. Aber auch außerhalb der Informatik finden Entwurfsmuster immer mehr Eingang. 19.1 Zweck - Pattern heisst auf Deutsch übersetzt Muster oder Beispiel - Design Patterns stellen wiederverwendbare Lösungen zu häufig auftretenden Problemen in der Software Entwicklung dar - Design Patterns kommen aus der Praxis und wiederspiegeln die Erfahrung von Experten - Die Verwendung solcher Muster erhöht die Qualität der Software und erleichtert die Kommunikation zwischen den einzelnen Entwicklern 19.2 Geschichtliches - Idee stammt ursprünglich aus der Architektur - 1977 hat Christopher Alexander ein Buch über die Verwendung von Mustern in der - Architektur geschrieben Ward Cunningham und Kent Beck nahmen 1987 die Idee von Alexander auf und entwarfen fünf Patterns für die User-Interface Programmierung Durchbruch der Software Patterns erst in den 90er Jahren 1994 wurde das Buch Design Patterns von den Autoren Erich Gamma, Richard Helm, John Vlissides und Ralph Johnson geschrieben Design Patterns entwickelte sich zu einem der Einflussreichsten Computer Bücher überhaupt und ist auch unter dem Begriff Gang of Four bekannt. © 2010 >> Stephan Metzler >> V 4.0 >> Seite 126 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns 19.3 JEE Pattern Im Zusammenhang mit JEE Applikationen sind spezielle Anforderungen erwünscht wie: - Transparenz - Stabilität - Performance JEE Entwurfsmuster stellen Idioms dar - also programmiersprache- und oft auch releaseabhängige Lösungen Die diskutierten Idioms sind nicht EJB/JPA EJB/JPA spezifisch, sondern gelten im Umgang mit JEE Serverkomponenten. 19.4 Service Locator - Suche und Erzeugung von EJB ist zeitintensiv und fehleranfällig - Namensdienste (JNDI, ...) - Komponentenverteilung (RMI-IIOP) - Factorycaching (Interfaces) Service Locator Idiom stellt ein Entwurfsmuster zur Kapselung der Technologie und eine Performancesteigerung zur Verfügung. Problem Bei einem Zugriff auf eine EJB muss zuerst ein Namensdienst initialisiert und die Verbindung zum Server hergestellt werden. Dazu werden produktspezifische Informationen benötigt. Die meisten JNDI Implementierungen basieren auf CORBA-Technologie, die eine Interpretation des Servers verlangt (z.B: "iiop://localhost:3700"). Dies kann bis zu mehreren Sekunden in Anspruch nehmen, da der Name zuerst von einem DNS aufgelöst werden muss. © 2010 >> Stephan Metzler >> V 4.0 >> Seite 127 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns Lösung Das Ermitteln von Dienstleistungen (z.B. JNDI Context) wird in den Locator verlagert. Dadurch verschwindet das sich wiederholende Downcasting über die narrow Methode von PortableRemoteObject im Service Locator. Anforderungen - bereits instanziierte Instanz des Home Objektes und Ressourcen werden gecached - Handels (robuste Referenzen) werden gecached - JNDI Technologie ist transparent für den Client Applikation Server Client EJB Service Locator - Zugriff auf JNDI - CACHE für ServerObjekte DBMS DAT A Implementation Der Service Locator kapselt die Zugriffe auf das JNDI und stellt ein Cache für die Serverschnittstellenobjekte zur Verfügung. Der Service Locator wird meist als Singelton implementiert, damit auch nur tatsächlich eine Instanz des InitialContext pro VM existiert. ServiceLocator to cache RemoteObject ► Ausschnitt public Object getRemoteObject(String name,boolean cached) throws Exception{ public static ServiceLocator getInstance() throws Exception{ if(instance==null) instance = new ServiceLocator(); return instance; } public EJBHome getHome(String name) throws Exception{ return getHome(name,true); } public static void main(String[] args) throws Exception{ Hashtable hash = new Hashtable(); hash.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory"); hash.put("java.naming.provider.url","iiop://localhost:3700"); } } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 128 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns 19.5 Business Delegate - Remotezugriff erfordert die Implementation entsprechender Technologie - z.B. RMI-IIOP - Client ist nicht an Technologie, sondern an Geschäftslogik interessiert - Business Delegate Idiom ermöglicht Kapselung der Technologie - Vereinfachung der Schnittstelle zur Geschäftslogik Problem Bei einem Zugriff auf die Geschäftslogik in einem EJB-Kontainer ist oft ein Remotezugriff notwendig. Ein Remotezugriff ist jedoch viel komplexer und zeitintensiver als ein Lokalzugriff. Zusätzlich müssen noch Exceptions (HostNotFoundException, StubNotFoundException, etc.) abgefangen werden. Lösung Die einzelnen Beans werden über eine zentrale Session Bean angesprochen. Diese hält die Instanzen der verschiedenen Beans und stellt diese dem Client in einer Schnittstelle zur Verfügung und kann auch Informationen an die anderen Beans weitergeben. Der Client produziert "Events" die vom Business Delegate Idiom "verteilt" werden und hat einen einfachen Zugriff auf die Geschäftslogik zur Verfügung. Applikation Server EJB Client DBMS DATA Business Delegate - Kapselung der BusinessLogik Implementation Das Business Delegate stellt die Schnittstelle zwischen Client und Geschäftslogik zur Verfügung. Dabei kapselt dieses Idiom die Zugriffslogik. Das Business Delegate wird vom Client instanziiert und benutzt. Die notwendigen Services werden durch den Service Locator beschafft. Business Delegate Interface ► wird dem dem Client zur Verfügung gestellt public interface BusinessDelegateIF { public CustomerVO getCustomer(String id); public CustomersVO[] getAllCustomerForZip(String zipPrefix); public CustomersVO[] getAllCustomers(); ... } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 129 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns 19.6 Value Object - limitierender Faktor in JEE Applikationen ist die Datenübertragung über das Netzwerk - von der Data Tier bis zur Client Tier und umgekehrt - Value Object Idiom verbessert die Performance und minimiert die Remote Methodenaufrufe Problem Der Zugriff auf ein EJB erfolgt oft über Remote Methodenaufrufe. Oft wird jedoch nur eine Teilmenge der benötigten Daten übermittelt (z.B: getter / setter Methoden). Sinnvoller ist es die gesammte benötigte Datenmenge (Datensatz) in einem Methodenaufruf zu übermitteln. Enterprise Beans haben in der Regel ganze Gruppen von Attributen, die vom Client in der Gruppe gebündelt abgerufen und gesetzt werden können. Auf diese Weise muss nicht für jedes Attribut einzeln eine Methode zum Setzen und Abfragen aufgerufen werden. Der Client erhält die Attribute in einem Value Object gebündelt. Lösung Die vielen "get"-Aufrufe werden bereits im EJB Container zusammengefasst und dem Client als Objekt übermittelt. Dieses Kontainer-Objekt besteht nur aus Zugriffslogik und keiner Geschäftslogik, ist somit ein Value Objekt und entspricht folgenden Anforderungen: - minimieren der Remote Methodenaufrufe an den Server - Die Geschäftsdaten werden als Objekt (Value Object) an den Client übergeben - das Auslesen der Objekt Attribute findet clientseitig statt Applikation Server Client EJB DBMS DATA Business Delegate ValueObject © 2010 >> Stephan Metzler >> V 4.0 >> Seite 130 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns Implementation Das Value Objekt wird durch eine serialisierbare Klasse repräsentiert, die lediglich zu Datenhaltungszwecken dient. Das Value Object wird auf der entfernten Maschine erzeugt und gefüllt, über das Netzwerk transferiert und lokal ausgelesen. Value Object als serialisierbare Klasse public class PersonVO implements Serializable{ public String id = null; public String name = null; public PersonVO(){} public PersonVO(String id, String name) { this.id = id; this.name = name; } public PersonVO(PersonVO person){ this.PersonVO(person.getId(), person.getName()); } // getter und setter } Grundsätzlich können Value Objects von folgenden Komponenten erzeugt werden: - Data Access Objects Session Façade (einer Session Bean, die den Zugriff auf ein Entity Bean managed) Business Delegate Session Bean Entity Bean Komponente der Präsentationsschicht Es handelt sich also grundsätzlich um Komponenten, die in der Geschäftslogik oder in der Integrationsschicht liegen und in der Lage sind, benötigte Daten zu beschaffen. Meistens werden jedoch die Value Objects von den Entity Beans erzeugt, da diese die notwendige "Persistence Schicht" repräsentieren. Das Value Object Idiom ist durch die JPA obsolet © 2010 >> Stephan Metzler >> V 4.0 >> Seite 131 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns 19.7 Session Facade - Geschäftslogik liegt typischerweise im EJB Container - durch Komponenten (EJBs) abgebildet - Client muss Zusammenhang der einzelnen Komponenten im Container kennen - Session Facade Idiom kapselt die Kontainer Komponenten durch ein Session Bean Problem Entity Beans bilden persistente Objekte ab, repräsentieren aber lediglich den Zustand der darunterliegenden Datenbank. Die EJBs sind in Bezug auf Wiederverwendbarkeit, Transaktionssteuerung sowie Zustandserhaltung nicht, oder nur mit sehr hohem Aufwand verbunden, vom Client trennbar. Wenn ein Client auf verschiedene Entity Beans zugreift und verschiedene Methoden der Entity Beans aufruft, um eine Aufgabe zu erledigen, kann dies verschiedene Probleme mit sich bringen. Zum einen erhöht sich der Netzwerk Traffic, des weiteren wird die Workflow Logik auf den Client verlagert, zum anderen sind die Methodenaufrufe durch die client-seitige Inszenierung möglicherweise nicht in einen notwendigen Transaktionszusammenhang gestellt. Die Entity Beans mit weiterer Processing Logik aufzublähen, ist nicht der richtige Lösungsansatz. Da die Entity Bean Schicht von der langfristigen Perspektive her aus verschiedenen Sichten und Aufgaben gesehen wird, wird der Einbau von Anwendungslogik zu Zwecken der Performance Verbesserung eher zu Wartungsproblemen führen. Deshalb sollte die Anwendungslogik, die eine Kette von Aufrufen von Entity Bean Methoden widerspiegelt, in einer Session Bean implementiert werden. Der Client ruft dann eine Methode der Session Bean auf, um seine Aufgabe zu erledigen. Die Methode der Session Bean übernimmt die Aufrufe der Methoden der verschiedenen Entity Beans. Lösung Lösung Was der Client möchte ist eine Schnittstelle, die ein Use Case abbildet. Dem Client kann es egal sein, wieviele Entity oder Session Beans diese Schnittstelle implementiert. Für den Client ist nur die korrekte Abbildung des Anwendungsfalles wichtig. Das Session Façade definiert eine neue "Schicht", die als Session Bean implementiert ist und folgende Anfgorderungen erfüllt: © 2010 >> Stephan Metzler >> V 4.0 >> Seite 132 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns - Abschirmung und Entkoppelung des Client vor Subsystemen ( Entity Bean, etc. ) Erhalt der Unabhängigkeit der Subsysteme Vereinfachung der Business Schnittstelle Implementierung von allgemeinen Diensten wie Caching, Authorisierung, etc. Zustandsverwaltung des Client Transaktionssteuerung Client Applikation Server EJB EJB Session Façade DBMS DATA Implementation In einer zusätzlichen Schicht, implementiert mit einer Session Bean, werden diese Anforderungen untergebracht. Falls ein Caching gefordert ist, muss die Session Bean stateful sein. Diese EJB entspricht in ihrer Funktionalität dem klassischen GoF Façade Pattern. Sie bietet eine einfache Schnittstelle und verbirgt die Komplexität der Subsysteme vor dem Client. Session Façade um einen Datensatz zu ändern ► Ausschnitt - startet eine Transaktion public void updatePerson (PersonVO person) throws Exception{ try{ getPerson(person.getId()).remove(); this.createPerson(person); }catch(Exception e){ throw new Exception("PersonBean.updatePerson " + e); } } © 2010 >> Stephan Metzler >> V 4.0 >> Seite 133 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns 19.8 JEE Entwurfsmuster JEE Idioms Entwurfsmuster Service Locator Business Delegate Session Facade Value Object Message Façade Service Activator EJB Command Business Interface DTO Factory Data Transfer Hash Map Value List Handler Data Transfer Row Set Data Access Object Version Number Muster zur Generierung von Primärschlüsselwerten Beschreibung Bedeutung für EJB kapselt teure Technologien kapselt Businesslogik, vereinfacht Zugriff kapselt die Kontainer Komponenten kapselt Business Data relevant obsolet, da keine RemoteExeptions durch die Spezifikation erzwungen obsolet, Custom DTO relevant nutzt asynchrone Kommunikation relevant Möglichkeit zur Gestaltung der Session Bean, durch Entkopplung des Clients stellt Konsistenz zwischen Beanklasse und Businessinterface sicher Erzeugung eines DTO durch Factory generische Variante zum DTO serverseitiges Speichern von Ergebnismengen disconnected RowSet für Serveranwendung ohne Entity Beans kapselt den Datenbank Zugriff Attribut kontrolliert Lost-Update-Problematik Generierung von Business Keys relevant obsolet für Custom DTO relevant relevant relevant relevant relevant, mit JPA jedoch leistungsfähiger in Spezifikation integriert in Spezifikation integriert © 2010 >> Stephan Metzler >> V 4.0 >> Seite 134 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Design Patterns H Trends Lerninhalte Agil Groovy DSL – Domain Specifi Languages NoSQL – Not Only SQL © 2010 >> Stephan Metzler >> V 4.0 >> Seite 135 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Programmierparadigma 20 Programmierparadigma Lat: <Paradigma Paradigma> Paradigma = begreiflich machen, (para = neben) und (digma = zeigen) wiki Ein Programmierparadigma ist das einer Programmiersprache oder Programmiertechnik zugrunde zugrunde liegende Prinzip. Prinzip. (einige) bekannte (Programmier)-Paradigmen Struktur - Strukturiert (WIE) - Imperativ (lineare Folge von Befehlen) - Prozedural (in Teilaufgaben zerlegt) Deklaration - Modular (Module als logische Einheiten, Funktion und Daten) - Deklarativ (WAS) - Funktional (ergebnisorientiert) - Logisch (logikbasiert) Orientation - Orientiert (WOZU) - Objekt (Kommunikation, polymorph – mehrere Formen) - Komponenten (abstrakt) - Aspekt (orthogonal freie Kombinierbarkeit unabhängiger Konzepte) - Agil (DRY Don't Repeat Yourself) Agilität 20.1 Agiles Programmieren Lat: <agil agilis agilis> is = flink, beweglich (Agile Softwareentwicklung reduziert Aufwand und Regeln) Skript- vs. Programmiersprachen Skriptsprache Ziel Einsatz Ausführung Typisierung Vorteile Programmiersprache Kombination bestehender Bausteine (Shell-Skript), Bibliotheken (Perl, Python) spezifisch: GUI (JavaScript), Reporting (Perl) interpretiert oder Bytecode schwach, flexibel, dynamisch schnelle Entwicklung (Python), Prototypen (Shell-Skript), kleine Systeme (Perl) Neuentwicklungen (C, C++) allgemein kompilierter Maschinencode streng, flexibel effiziente Anbindung, Ausnutzung von Ressourcen (C++, Java) © 2010 >> Stephan Metzler >> V 4.0 >> Seite 136 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Programmierparadigma Historie der Skriptsprachen JCL 1963 (Job Control Language) AWK 1977 1977 (Aho Weinberger Kernighan) Sh 1978 1978 (Bourne Shell) Perl 1987 (Practical Extraction and Report Language) Python 1990 1990 (Monthy Python) Tcl 1988 1988 (Tool Command Language) PHP 1995 1995 Ruby 1995 1995 JavaScript 1995 1995 (Personal Home Page) (Eng: Rubin) (ECMA 262) Groovy 2003 (JSR 241) 20.2 Groovy wiki dynamisch typisierte typisierte ProgrammierProgrammier- und Skriptsprache für die Java VM verbindet JavaJava-Syntax mit den Konzepten von Ruby. Ruby. Groovy Groovy ermöglicht: - pragmatisches (selbsterklärend) extremes (code a little, test a little) agiles (YWGWYS) funktionales (funktionale Abhängigkeiten) objektorientiertes (alles sind Objekte) abstrahiertes (wieder verwendbarer Code) effizientes (weniger Codeumfang) einfaches (Syntax) Programmieren. Paradigmen objektorientiert, Skriptsprache, teilweise deklarativ Erscheinungsjahr 2003 Entwickler The Codehaus Aktuelle Version 1.7 (2010) Typisierung stark, statisch, dynamisch Betriebssystem plattformunabhängig Lizenz Open Source, Apache Software License 2.0 Groovy. Codehaus http://groovy.codehaus.org/ © 2010 >> Stephan Metzler >> V 4.0 >> Seite 137 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Programmierparadigma 20.3 DSL Domain Specific Language wiki Eine domänenspezifische Sprache (engl. domaindomain-specific language, language, DSL) ist eine formale Sprache, Sprache, die speziell für ein bestimmtes Problemfeld (die Domäne) Domäne) entworfen und und implementiert wird. Beim Entwurf einer DSL wird man bemüht sein, einen hohen Grad an Problemspezifität zu erreichen: die Sprache soll alle Probleme der Domäne darstellen können und nichts darstellen können, was auss ausserhalb sserhalb der Domäne liegt. Dadurch ist sie sie durch Domänenspezialisten ohne besonderes Zusatzwissen bedienbar. Idee - weniger Redundanz HTTP deklarative Beschreibung eines Sachverhaltes bessere Lesbarkeit weniger technischer Code domänenspezifische, statische Validierung leichte Erlernbarkeit, aufgrund des beschränkten Umfangs DSL Domain DSL http Deamon SQL Domain DBMS 20.4 NoSQL (Not only SQL) wiki NoSQL is a movement promoting a loosely defined class of nonnon-relational data stores that break with a long history of relational databases. These data stores may not require fixed table schemas, schemas, usually avoid join operations and typically scale horizontally. horizontally. im Web 2.0 sind schreibende Zugriffe wichtig (nicht nur lesende) - für Anwendungen, wo endgültige Konsistenz der Daten gewährleistet sein muss - Twitter - Facebook - traditionell: RDBMS - Constraints - Transaktionen - Locking - SQL - RDBMS haben Probleme mit der Verarbeitung und Skalierung grosser Datenmengen - neuer Ansatz - NoSQL z.B. "Key/Value" Storage © 2010 >> Stephan Metzler >> V 4.0 >> Seite 138 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Programmierparadigma I Referenzen Lerninhalte Bücher Referenzen © 2010 >> Stephan Metzler >> V 4.0 >> Seite 139 >> total: 140 Seiten JPA 2.0 >> Java Framework >> Anhang 21 Anhang - Bücher - Online Referenzen Bücher ISBN 987987-3-8986489864-431431-0 978978-3-8680286802-014014-4 3-82738273-21842184-0 0-1313-142246142246-4 3-82738273-21242124-7 3-8273 827373-18621862-9 0-76457645-76827682-8 9-780321780321-118899 1-932394932394-8888-5 0-1313-140264140264-1 Titel EJB 3 professionell JPA mit Hibernate J2EE, Einstieg für Anspruchsvolle Core J2EE Patterns, Best Practices and Design Strategies J2EE Patterns, Entwurfsmuster für die J2EE Entwurfsmuster, Elemente wiederverwendbarer objektorientierter Software Mastering Enterprise JavaBeans Enterprise Java Security Java Persistence with Hibernate J2EE Security Online Referenzen URL http://www.java.com http://www.java.com http://www.jboss.org http://www.hibernate.org http://www.ejbkomplett.net Inhalt Java JBoss Hibernate EJB © 2010 >> Stephan Metzler >> V 4.0 >> Seite 140 >> total: 140 Seiten