Pattern
JPA
JPA steht für Java Persistence API und ist eine Schnittstelle für Java-Anwendungen, welche die Zuordnung und Übertragung von Objekten zu Datenbankeinträgen vereinfacht.
JPA vereinfacht die Lösung des Problemes, Laufzeitobjekte über eine Sitzung hinaus zu speichern.
Die API ist im Package javax.persistence definiert und besteht aus folgenden Komponenten:
Persitence Entity
Eine Persistence Entity ist ein Plain Old Java Object (POJO), welches normalerweise auf einer einzigen Tabelle in der relationalen Datenbank abgebildet wird. Instanzen einer Persitence Entity entsprechen den Zeilen der Tabelle.
Je nach Designvorgabe können Persistence Entities als einfache Datenhaltungs-Klassen der als Business-Objekte inklusive Business-Logik realisiert werden.
Objektrelationale Metadaten
Die Beziehungen zwischen Tabellen wird mit objektrelationalen Metadaten ausgedrückt. Die objektrelationalen Metadaten werden entweder als Annotation, oder in ausgelagerten XML-Datein definiert.
Java Persistence Query Language
Die Java Persistence Query Language (JPQL) wird verwendet, um Abfragen bezüglich der in der Datenbank gespeicherten Entitäten durchzuführen.
Die Abfrage ähneln SQL-Abfragen, beziehen sich aber auf Entitäten, statt Datenbanktabellen.
Die JPA-Implementierungen überführen die in JPQL formulierten Abfragen zur Laufzeit in ein SQL-Statement, das vom Zieldatenbanksystem verstanden wird.
Durch diese Abstraktion kann das Datenbanksystem transparent ausgetauscht werden, während die Java-Klassen vollständig erhalten bleiben.
Enterprise JavaBean
Enterprise JavaBeans (EJB) sind stan standardisierte Komponenten innerhalb eines Java-EE-Servers (Java Enterprise Edition). EJB vereinfacht die Entwicklung von mehrschichtiger verteilter Softwaresysteme mit Java.
Mit EJB können wichtige Konzepte für Anwendungen wie Transaktions- und Sicherheitsdienste umgesetzt werden.
Entity Bean
Enitity Beans modellieren die persistenten Daten des Systems.
Die Persistenz kann entweder vom Entwickler programmiert („Bean Managed Persistence“, BMP) oder von einem EJB-Container bereitgestellt werden („Container Managed Persistence“, CMP).
Bei CMP wird im Deployment Descriptor der Name eines abstrakten Schemas definiert, was meistens der Name der Datenbank ist.
Session Bean
Session Beans bilden Vorgänge ab, welche der Nutzer mit dem System durchführt.
Es gibt zustandslose (stateless), sowie zustandbehaftete (stateful) Session Beans
Eine zustandbehaftete Session Bean hat ein Gedächtnis und kann dadurch Informationen aus einem Methodenaufruf speichern, damit sie bei einem späteren Aufruf einer Methode diese Informationen wieder zur Verfügung stellen kann.
Zustandsbehaftung wird durch die Vergabe einer eindeutigen ID umgesetzt.
Message Driven Bean
Message Driven Beans sind Komponenten, welche die EJB-Systeme für asynchrone Kommunikation zugänglich machen. Dazu wird der Java Message Service (JMS) verwendet. Diese Beans werden oft für die kommunikation mit Legacy-Systemen verwendet.
Auch für asynchrone Kommunkation, wie z.B. das Versenden einer E-Mail werden Message Driven Beans verwendet.
Web Services
Ab Version 1.4 erlaubt die J2EE-Spezifikation den Aufruf von Stateless Session Beans als Web Services und beschreibt einen Mechanismus, der die Schnittstelle eines Web Service auf die Schnittstelle einer EJB abbildet.
Transaktionen
NotSupported
Die NotSupported Methode unterstützt keine Transaktionen.
Der EJB-Container gibt keinen Transaktionskontext an die Methode und unterbricht die Transaktion bis zum Ende des Methodenaufrufs. Wenn die Methode andere EJBs aufruft, so laufen auch diese ohne Transaktion.
Required (Default)
Die Required Methode kann nur in einer Transaktion aufgerufen werden.
Falls der Aufrufer nicht Teil einer Transaktion ist, beginnt der EJB-Container eine neue Transaktion, die nach dem Verlassen der Methode wieder beendet wird.
Die Required Methode ist der Standart, falls nichts anderes definiert wurde.
Supports
Diese Methode kann in und ausserhalb einer Transaktion aufgerufen werden.
RequiresNew
Die RequiresNew Methode benötigt eine eigene Transaktion.
Beim Aufruf dieser Methode wird immer eine neue Transaktion begonnen, welche mit der Rückkehr aus dem Aufruf endet.
Mandatory
Bei Mandatory muss der Aufrufer teil einer bestehenden Transaktion sein.
Never
Die Never Methode darf nie in einer Transaktion aufgerufen werden.
DI
Dependency Injection (DI) ist ein Entwurfsmuster in der objektorientierten Entwicklung, welches die Abhängigkeiten eines Objekts zur Laufzeit reglementiert.
Wenn ein Objekt bei der Initialisierung ein anderes Objekt benötigt, wird die Abhängigkeit nicht beim Objekt selbst, sondern an einem zentralen Ort hinterlegt.
Umsetzung
Es existieren drei hauptsächliche Arten zum Setzen einer Referenz.
Constructor Injection
Abhängigkeiten von anderen Klassen werden über Konstruktoren zur Verfügung gestellt.
class Abhängiges {
private Abhängigkeit abhängigkeit;
//Konstruktor
public Abhängiges(final Abhängigkeit abhängigkeit) {
this.abhängigkeit = abhängigkeit;
}}
class Injizierer {
void methode() {
final Abhängigkeit abhängigkeit = … ;
final Abhängiges abhängiges = new Abhängiges(abhängigkeit) ;
}}
Interface Injection
Das Modul der injizierenden Klasse definiert eine Schnittstelle, die von abhängigen Klassen implementiert werden muss, um zur Laufzeit die Abhängigkeiten zur Verfügung gestellt zu bekommen.
interface IInjizierbar {
void injiziere(final Abhängigkeit abhängigkeit);}
class Abhängiges implements IInjizierbar {
private final Abhängigkeit abhängigkeit;
public void injiziere(final Abhängigkeit abhängigkeit) {
this.abhängigkeit = abhängigkeit;
}}
class Injizierer {
void methode() {
final Abhängigkeit abhängigkeit = … ;
final IInjizierbar injizierbares = … ;
injizierbares.injiziere(abhängigkeit);
}}
Setter Injection
Die abhängige Klasse stellt Methoden zur Verfügung, die dazu verwendet werden, die Abhängigkeiten zur Verfügung zu stellen.
class Abhängiges {
private Abhängigkeit abhängigkeit;
public void setAbhängigkeit(final Abhängigkeit abhängigkeit) {
this.abhängigkeit = abhängigkeit;
}}
class Injizierer {
void methode() {
final Abhängiges abhängiges = … ;
final Abhängigkeit abhängigkeit = … ;
abhängiges.setAbhängigkeit(abhängigkeit);
}}