JPA - Die Lösung der Persistenz oder wieder nur ein OR-Mapper ? Stefan Bacher, Klaus Huthmacher; Architektur | JBFOne 2008
Ziel dieses Vortrags Verständnis für die Problematik des OR-Mappings Vermittlung der Grundlagen des Java Persistence API Weiterentwicklung DAM mit JPA
Agenda OR-Mapping – Die Herausforderung in der Anwendungsentwicklung OR-Mapping in der FIDUCIA IT AG JPA – Java Persistence API DAM – Data Access Management mit JPA Ausblick
Agenda OR-Mapping – Die Herausforderung in der Anwendungsentwicklung OR-Mapping in der FIDUCIA IT AG JPA – Java Persistence API DAM – Data Access Management mit JPA Ausblick
OR-Mapping – Die Herausforderung in der Anwendungsentwicklung Persistenz ist eines der Grundkonzepte der objektorientierten Anwendungsentwicklung Anwendungen nutzen normalerweise persistente Daten aus (relationalen) Datenbanken setAge(50) Kunde ? getAdress() Select … Update … addKonto(„1234“) Adresse Konto Insert …
Problematik Objektorientierte Programmiersprachen kapseln Daten und Verhalten in Objekten und haben eine eindeutige Identität Relationale Datenbanken legen Daten in Tabellen ab und basieren auf dem mathematischen Konzept der relationalen Algebra Paradigmen sind grundlegend verschieden, bekannt als „impedance mismatch“ Ansätze zur Auflösung des konzeptionellen Widerspruches Objektorientierte Datenbank Erweiterung der Programmiersprache um relationale Funktionen OR-Mapper
Lösungsansätze Objektorientierte Datenbank Kein Mapping notwendig Daten können nicht ohne Anwendung sichtbar gemacht werden Komplexe Abfragen werden schnell kompliziert Am Markt nicht etabliert Erweiterung der Programmiersprache um relationale Funktionen Verwendung von Objekten wird eingeschränkt OR-Mapper Schicht zwischen Anwendung und Datenbank Transparent für den Anwendungsentwickler Am weitesten verbreitet OR-Mapper
Objektrelationales Mapping OR-Mapper als Vermittler zwischen den Welten Anwendungsentwicklung merkt (fast) nichts vom Paradigmenbruch Laden, Speichern, Aktualisieren oder Sperren von Objekten geschieht ohne gesonderte Mitwirkung des Anwendungsentwicklers ABER: Abstraktion von der Speicherform der Daten bekommt man nicht zum Nulltarif aufwändiges, explizites Mapping von Klassen auf Relationen ist notwendig Schwierigkeiten richtige Wahl der Abbildungsalternative für folgende Aspekte Abbildung von Vererbung Abbildung von Beziehungen … OR-Mapper
Objektrelationales Mapping in Java Persistierungsmöglichkeiten Manuelle Persistenz (handgeschriebener Code) JDBC iBATIS Persistenzframeworks Proprietäre Tools und Frameworks seit 1996 Standardisierungen seit 2000 beginnend mit EJB
Proprietäre Frameworks TopLink Kommerzielles Produkt der Firma WebGain Eines der ersten OR-Mapping-Frameworks für Java Durch Oracle übernommen und als Opensource bereit gestellt Basis für EclipseLink (Persistenz-Projekt der Eclipse-Gemeinde) Hibernate Opensource Produkt Lange Zeit der „quasi“-Standard für OR-Mapping … Viele weitere Produkte, die sich am Markt nicht durchgesetzt haben
Standardisierungen EJB (Enterprise Java Beans) Persistenz in Applikationsservern In den ersten Versionen sehr schwergewichtig Mit EJB 3.x leichtgewichtiger und einfacher zu handhaben JDO Definition einer Persistenzschnittstelle für Java Implementierung durch verschiedene Provider JPA Zweiter Versuch der Definition einer Persistenzschnittstelle für Java Definition als Bestandteil von EJB 3.x Erfahrungen von JDO, Hibernate und TopLink flossen in die Entwicklung ein
Agenda OR-Mapping – Die Herausforderung in der Anwendungsentwicklung OR-Mapping in der FIDUCIA IT AG JPA – Java Persistence API DAM – Data Access Management mit JPA Ausblick
? DAM / JDO Kunde Adresse Konto setAge(50) getAdress() Update … addKonto(„1234“) getAdress() ? Select … Update … Insert …
DAM / JDO JDO als Basis Produkt XIC (Xcalia Intermediation Core) der Firma xcalia als Implementierung Generativer Ansatz Beschreibungsdateien aus RSA oder Innovator Generierung der Persistenzschicht über DAM-Generatoren Implementierung der DB Zugriffe in JDOQL
JDO – Transparente Persistenz Kein spezieller import public class Employee extends Person { public String name; private java.util.Date birthday; private int salary; public Company company; public IActivity activity; Vector awards; public void bonus(int more) { salary += more; } Vererbung Interfaces Collections Keine Accessors etc. Dies ist eine persistente Klasse!
JDO - Metadaten Objektwelt Datenbankwelt JDO Metadaten POJO JDO IMPL API POJO POJO DB POJO = Plain Old Java Object
JDO - Enhancing Java-Source Erweiterung des Bytecodes der persistenten Klassen um die JDO-Schnittstelle und deren Implementierung Basiert auf Metadaten Enhancing ist standardisiert Compiler Bytecode Metadaten ENHANCER Bytecode
DAM / JDO – Mapping der Objektmodelle DO-Modell SO-Modell -vorname -gebDatum SOKunde -personNr -name SOPerson -betrag SOFirma -adrNr -ort -strasse -hausNr -telNr SOAdresse -refAdresse 1 -kontoNr -saldo -zins -kontoArt SOKonto -colKonten * AMPerson AMKonto -colKonten -numPersonNr -numKontoNr -strName -monSaldo 1 * -monZins -keyKontoArt DAM Mapping AMFirma AMKunde -refAdresse -monBetrag -strVorname AMAdresse -datGebDatum 1 -numAdrNr -strOrt -strStrasse 1 -numHausNr -strTelNr DO (DataObjects)-Klassen werden nicht direkt persistiert DOs werden in persistierbare Objekte abgebildet (StorableObjects, SO) Transfer der Daten zwischen DO-Modell und SO-Modell durch generierte Mapper-Klassen StorableObjects werden in Entitäten der Datenbank abgebildet Transfer in die Datenbank über JDO J D O / L i d o M a p n g Person PK persnr name Konto kontonr saldo zins kontoart FK1 Kunde vorname gebdat adrnr Firma bilanz Adresse ort strasse hausnr telNr DB-Modell
Der Entwicklungsprozess - vom Modell zur Datenbank Modellierung Header Footer ACT JDO ERM Generator - Konfiguration Generator Builder ferdisch Test Implementierung Activity Implementierung DAM zum selber basteln Java Compiler Builder auf - JDO drübber Enhance Builder DDL Datenbank Objekte persistieren Test
DAM – Definition der Activities <activitymodel project="tst" version="1.0"> <activity-component name="Kunde" package="dam"> <activity-function comment="" name="insertKunde" package="dam.activities"> <input-data comment="" name="kd" type=„AMKunde" type-package="dam.model"/> <output-data comment="" type="AMKunde" type-package="dam.model"/> </activity-function> <activity-function comment="" name="kundeByName" package="dam.activities"> <input-data comment="" name="kname" type="String" type-package="java.lang"/> </activity-component> </activitymodel>
DAM – Generierte Activities public AMAuftrag aendereAuftrag (AMAuftrag auftr) throws AbstractDataMgmtSystemException, AbstractDataMgmtApplicationException { //USER_CODE_updateAuftrag_AMAuftrag_{1} DataMgmtAssertion.notNull(null,"method updateAuftrag not implemented"); return null; }
DAM – Speichern eines Objekts IWorkspace4Mapper ws4Mapper = (IWorkspace4Mapper) ws; SOKundeMapper mapper = new SOKundeMapper(knd); // Insert des Root-Objektes ws4Mapper.insert(mapper); // Alle Subelemente der Wurzel hinzufuegen IWorkspace4Model ws4Model = (IWorkspace4Model) ws; ws4Model.write(mapper);
DAM – Suchen von Datensätzen String constraint = "name==\""+kndname+\""; …… IQuery qy = qyFactory.createQuery(ws, SOKunde.class, constraint); ICursor it = qy.execute(); try { for ( ; it.hasNext(); ) IStorableReadMapper mapper = new SOKundeMapper(qFactory); Pair p = it.next(ws, mapper); AMKunde kd = (AMKunde)((SOKundeMapper)p.getFirst()).getAMKunde(); KundenListe.add(kd); } return KundenListe; Hier ist eine typische Abfrage mit DAM-Mitteln zu sehen. Es wird zunächst eine Bedingung für die Abfrage definiert Die Abfrage wird dann generiert und ausgeführt. Für jeden gefundenen Datensatz wird dann das entsprechende AM erzeugt und mit den gelesenen Daten aus der Datenbank versorgt. Die Liste der gefundenen Daten ist das Ergebnis der Abfrage.
JDO / Probleme Updates auf Massendaten Objekte müssen vor dem Ändern / Löschen immer geladen werden update … where … ist nicht möglich Führt zu Speicher und Performanceproblemen einheitliche Verwendung der JDO Schnittstelle kann nicht immer gehalten werden Performance Lösungsmöglichkeiten DB Zugriff über andere Schnittstellen (nicht einheitlich) DBObject JPA (dann durchgängig) JPA
Agenda OR-Mapping – Die Herausforderung in der Anwendungsentwicklung OR-Mapping in der FIDUCIA IT AG JPA – Java Persistence API DAM – Data Access Management mit JPA Ausblick
JPA – Java Persistence API Im Zuge der EJB 3.0 Spezifikation wurde die JPA als Standard für das objektrelationale Mapping von POJOs auf relationale Datenbanken spezifiziert Erfahrungen aus Produkten wie Hibernate, JDO, TopLink sind eingeflossen EJB 3.0 implementiert die JPA, doch JPA kann auch außerhalb eine EJB-Containers als Persistenz-Framework verwendet werden
JPA – Java Persistence API JPA soll JDO überflüssig machen „Der“ Persistenz-Mechanismus für EJB- und Standard-Java-Anwendungen Implementierungen vieler Hersteller Hibernate Entity Manager TopLink Essentials (Oracle/Sun) EclipseLink JPA OpenJPA (Apache)
JPA – Eigenschaften I Transparente Persistenz Entitäten sind POJOs (Plain Old Java Objects) Keine speziellen Interfaces Kein Enhancement des Bytecodes Keine erforderlichen Callbackmethoden Programmier-Interface für das Lesen, das Speichern und die Abfrage von Entitäten Abfrage der Daten erfolgt unter Verwendung einer SQL-ähnlichen Abfragesprache JPA ist in unterschiedlichen Umgebungen lauffähig Standalone in der JAVA SE – Umgebung Innerhalb eines J2EE - Containers
JPA – Eigenschaften II Mapping über Annotationen oder xml-Beschreibung Assoziationen 1 – 1 1 – n m – n Denormalisierung durch eingebettete Objekte Vererbung per-concrete-class per-class single-table Transaktionen @Entity public class Customer { @Id private String name; @OneToOne private Account account; public String getName() { return name; } public void setName(String name) { this.name = name; } public Account getAccount() { return account; } public void setAccount(Account account) { this.account = account;
JPA – Eigenschaften III Mächtige (SQL-nahe) Abfragesprache JPQL Objektorientiert Joins, Unterabfragen, Projektionen, Aggregationsfunktionen, Gruppierungen RDBMS-unabhängig direktes SQL möglich Mengenoperationen Bemerkenswerteste Neuerung Direkte Formulierung von Update- und Delete-Anweisungen Kein Einsatz von JDBC mehr notwendig SELECT m, count(i) FROM Magier m JOIN m.items i GROUP BY m UPDATE Magier m SET m.mana = m.mana + 10 WHERE m.name = „Dumbledore“
Fazit JPA ist ein gelungener Standard für Persistenz Leichtgewichtiges Programmiermodell durch die Verwendung von Annotationen Persistenz fügt sich nahtlos in die Java-Entwicklung ein JPAQL ermöglicht komplexe RDBMS-unabhängige Abfragen mit derselben Technologie, die für Unternehmensanwendungen verwendet wird Mengenoperationen zur Massenverarbeitung von Daten sind möglich ABER: Standard reicht zum Teil nicht aus Es muss auf Funktionalitäten des zugrundeliegenden Providers zugegriffen werden
Agenda OR-Mapping – Die Herausforderung in der Anwendungsentwicklung OR-Mapping in der FIDUCIA IT AG JPA – Java Persistence API DAM – Data Access Management mit JPA Ausblick
DAM / JPA (Hibernate) vs. DAM / JDO (XIC) Alle Testfälle sind gleich aufgebaut! Für ein Objektgeflecht werden typischen CRUD Operationen getestet Die Testfälle werden sowohl für JPA als auch für JDO durchlaufen Im ersten Lauf werden die SQL Statements ermittelt Vor dem Ermitteln der Laufzeiten wird das „Logging“ abgeschaltet Jeder Test wird fünf mal durchlaufen und dessen Laufzeit gestoppt und gespeichert Es werden fünf Messungen gemittelt und als Grundlage für die folgende Diagramme genutzt.
DAM / JPA (Hibernate) vs. DAM / JDO (XIC) Insert
DAM / JPA (Hibernate) vs. DAM / JDO (XIC) Select
DAM / JPA (Hibernate) vs. DAM / JDO (XIC) Update
DAM / JPA (Hibernate) vs. DAM / JDO (XIC) Delete
DAM / JPA (Hibernate) vs. DAM / JDO (XIC) Fazit Die JPA Implementierung von Hibernate ist in allen Testfällen deutlich schneller als die JDO Implementierung von XIC. JPA erzeugt beim Insert doppelt so viele Statements wie JDO Update, Select und Delete sind von der Anzahl der Statements sehr ähnlich. Trotz der z.T. höheren Anzahl der Statements ist die JPA Implementierung wesentlich schneller. Wenn man die Abfragesprachen für die JPA (JPAQL und SQL) und die JDO (JDOQL) vergleicht, schneidet die JPAQL durch ihre SQL ähnliche Syntax und das daraus folgende leichtere Verständnis sowie durch einen größeren Funktionsumfang besser ab.
Agenda OR-Mapping – Die Herausforderung in der Anwendungsentwicklung OR-Mapping in der FIDUCIA IT AG JPA – Java Persistence API DAM – Data Access Management mit JPA Ausblick
Ausblick - JPA JPA 2.0 Early Draft Review 07/2008 (JSR 317) Final Release Q4/2008 Erweiterung der OR-Mapping-Funktionalität Erweiterung der Abfragesprache Portabilität der Implementierungen EclipseLink als Referenzimplementierung
Ausblick - DAM Integration von JPA in DAM Erweiterung um temporale und bitemporale Aspekte der Datenhaltung Historisierung von Objekten (Transaktionszeit) Was wurde wann von wem am Objekt geändert Lückenlose Änderungshistorie Zusätzlich fachliche Gültigkeitszeit (Bitemporalität) Zeitraum, in dem ein Datenelement in der realen Welt fachlich gültig ist
Zusammenfassung Mit JPA wurde ein neuer Standard für die Persistenz von Java-Anwendungen definiert JPA ist die konsequente Weiterentwicklung aus vorherigen Standards und proprietären OR-Mapping-Frameworks Die Lösung für alle Probleme des OR-Mappings ist jedoch auch durch JPA nicht gegeben, die Problematik des „impedance mismatch“ bleibt OR-Mapping ist und bleibt die Herausforderung der Anwendungsentwicklung
Fragen? – Diskussion? Stefan Bacher Anwendungsentwicklung Technische Architektur stefan.bacher@fiducia.de +49 (0) 89 9943 - 3398 Klaus Huthmacher klaus.huthmacher@fiducia.de +49 (0)89 9943 - 3134
Ihr IT-Partner Vielen Dank