Beispiel: Container Managed Relationship zweier Entity Beans (IBM WebSphere)
Beispiel für zwei Container Managed Entity Bean, auf die per Webclient zugegriffen wird.
Zwischen den beiden Beans besteht eine Container Managed Relationship.
Dieses Beispiel entspricht (mit Modifikationen) dem Beispiel "KuchenZutat" für den SunAppServer. "KuchenZutatAutoPK"
entfällt, da WebSphere keine automatisch generierten Primary Keys unterstützt.
Die Deployanleitung bezieht sich auf IBM WebSphere.
Hier gibt es das WebSphere-Projekt zum Download (dies ist ein Projektaustausch-Export, die Importanleitung
findet man im Stateless-Beispiel): KuchenZutatExport.zip
Aufbau des Beispieles
a) Entity Bean-Klasse für Kuchen mit Local-Interfaces.
b) Entity Bean-Klasse für Zutat mit Local-Interfaces.
c) Webclient
Anlegen der Application
Ein Unternehmensanwendungsprojekt mit dem Namen "KuchenZutat" erstellen.
Zu erzeugende Module definieren. Dieses Beispiel benötigt ein EJB-Projekt und
ein Anwendungsclientprojekt.
Die J2EE-Hierarchie sollte so aussehen:
Anlegen der Entity Bean "Kuchen"
Es wird eine neue Entity Bean angelegt. Dazu in der J2EE-Hierarchie "EJB-Module" -> "KuchenZutatEJB" ->
"Entity Beans" wählen und im Contextmenü den Punkt "Neu" -> "CMP-Bean" auswählen.
Im ersten Schritt wird das EJB-Projekt gewählt, in dem die Bean erstellt werden soll.
In Schritt 2 wird der Typ der Bean festgelegt: Es handelt sich um eine Bean mit Container Managed
Felder, und zwar nach CMP-Version 2. Bean-Name und Package-Name müssen angegeben werden.
In Schritt 3 wird festgelegt, dass wir hier ein Local Interface haben wollen.
In der unteren Liste fügen wir die Container Managed Attribute zu.
Da IBM WebSphere keine automatisch generierten Primary Keys kennt, müssen wir den Primary Key manuell erzeugen
(siehe letztes Beispiel KuchenSingle). Wir fügen also ein Feld "id" von Typ "java.lang.Integer" zu.
Das einzige Datenfeld unserer Bean ist "Name". Dieses wird ebenfalls zugefügt.
Das Ergebnis von Schritt 3 sollte so aussehen:
Damit haben wir das Erstellen der Bean abgeschlossen. Die weiteren Schritte erfolgen, sobald wir die zweite Bean "Zutat"
angelegt haben.
Anlegen der Entity Bean "Zutat"
Es wird eine neue Entity Bean namens "Zutat" angelegt.
In Schritt 2 wird der Typ der Bean festgelegt: Es handelt sich um eine Bean mit Container Managed
Felder, und zwar nach CMP-Version 2. Bean-Name und Package-Name müssen angegeben werden.
In Schritt 3 wird festgelegt, dass wir hier ein Local Interface haben wollen.
In der unteren Liste fügen wir die Container Managed Attribute zu.
Da IBM WebSphere keine automatisch generierten Primary Keys kennt, müssen wir den Primary Key manuell erzeugen
(siehe letztes Beispiel KuchenSingle). Wir fügen also ein Feld "id" von Typ "java.lang.Integer" zu.
Das erste Datenfeld unserer Bean ist "ZutatName". Dieses wird ebenfalls zugefügt.
Das zweite Datenfeld unserer Bean ist "Menge". Dieses wird ebenfalls zugefügt.
Das Ergebnis von Schritt 3 sollte so aussehen:
Damit haben wir das Erstellen der Bean abgeschlossen. Jetzt können wir uns an die Nachbearbeitung der Beans machen.
Nachbearbeitung der KuchenBean
Die Methode "findAll" muss implementiert werden. Dazu zum EJB-Implementierungsdeskriptor unter "Abfragen"
eine neue hinzufügen.
Die Query lautet
select object(o) from Kuchen o order by o.name
Das Ergebnis sollte so aussehen:
Die Logik für das Verwalten des Primary Keys muss implementiert werden (manuell zu erzeugen !):
Wir definieren eine finder-Methode, die den Datensatz mit der Maximalen Id zurückliefert (mittels einem Subselect).
Dies geschieht an der gleichen Stelle im "EJB-Implementierungsdeskriptor" wie die findAll-Methode.
Die Finder-Methode hat den Namen "findByMaxId", sie steckt im Local-Interface, und hat als
Rückgabewert eine einzelne Kuchen-Bean.
Die Query sieht so aus:
select object(o) from Kuchen o where o.id in (select max (oInner.id) from Kuchen oInner)
Es wird also in einer inneren Abfrage die maximale ID geholt, dann wird der Datensatz zu dieser ID geholt.
(Dies führt zu FinderExceptions, wenn noch keine Beans in der Datenbank vorhanden sind).
Weitere Nachbearbeitung:
In der Methode "ejbCreate" entfernen wir den Parameter "id" (im Home-Interface nachziehen !)
sowie den Aufruf von "setId(id)".
Stattdessen wird die ID mittels einer einzufügenden Methode "getNextId" abgerufen (diese wiederum greift auf "findByMaxId"
zu) und in der Bean gesetzt:
"this.setId (this.getNextId() )".
Die Methode "ejbCreateByName" (Rückgabewert: Integer !) muss zugefügt werden. Natürlich muss auch "ejbPostCreateByName"
implementiert werden. Diese neue Create-Methode muss auf das LocalHome-Interface hochgestuft werden.
Nachbearbeitung der ZutatBean
Die Methode "findAll" muss implementiert werden. Dazu zum EJB-Implementierungsdeskriptor unter "Abfragen"
eine neue hinzufügen.
Die Query lautet
select object(o) from Zutat o order by o.zutatName
Die Logik für das Verwalten des Primary Keys muss implementiert werden (manuell zu erzeugen !):
Wir definieren eine finder-Methode, die den Datensatz mit der Maximalen Id zurückliefert (mittels einem Subselect).
Dies geschieht an der gleichen Stelle im "EJB-Implementierungsdeskriptor" wie die findAll-Methode.
Die Finder-Methode hat den Namen "findByMaxId", sie steckt im Local-Interface, und hat als
Rückgabewert eine einzelne Zutat-Bean.
Die Query sieht so aus:
select object(o) from Zutat o where o.id in (select max (oInner.id) from Zutat oInner)
Es wird also in einer inneren Abfrage die maximale ID geholt, dann wird der Datensatz zu dieser ID geholt.
(Dies führt zu FinderExceptions, wenn noch keine Beans in der Datenbank vorhanden sind).
Das Ergebnis mit den beiden Find-Methoden sollte so aussehen:
Weitere Nachbearbeitung:
In der Methode "ejbCreate" entfernen wir den Parameter "id" (im Home-Interface nachziehen !)
sowie den Aufruf von "setId(id)".
Stattdessen wird die ID mittels einer einzufügenden Methode "getNextId" abgerufen (diese wiederum greift auf "findByMaxId"
zu) und in der Bean gesetzt:
"this.setId (this.getNextId() )".
Die Methode "ejbCreateByNameMenge" (Rückgabewert: Integer) muss zugefügt werden. Natürlich muss auch "ejbPostCreateByNameMenge"
implementiert werden. Diese neue Create-Methode muss auf das LocalHome-Interface hochgestuft werden.
Erstellen der 1:n-Relationship
Im EJB-Implementierungsdeskriptor wählt man die Kuchen-Bean und geht zu "Beziehungen".
Man klickt auf "Hinzufügen". Im ersten Schritt des Assistenten wählt man die beiden zu verknüpfenden Beans aus.
Im nächsten Schritt gibt man die Kardinalität der Beziehung an und definiert die Feldnamen der Properties.
Als einzige Änderungen sind hier vorzunehmen:
Den Namen der Property "zutat" ändern wir in "zutaten", da ein Kuchen eine Liste von Zutaten zurückliefert.
Auf der Zutat-Seite wird als Multiplizität "Many" gewählt, da ein Kuchen aus 0 bis n Zutaten besteht.
Außerdem wird mehrstufiges Löschen ("on delete cascade") aktiviert.
Es werden automatisch in der Kuchen-Bean die Methoden "getZutaten" und "setZutaten" angelegt. In der ZutatBean
wird "getKuchen" und "setKuchen" angelegt. Die Properties erkennt man auch in der J2EE-Hierarchie.
Nachbearbeitung:
In der KuchenBean werden die beiden Methoden "addZutat" und "getZutatenListe" (umwandeln der Zutaten-Collection aus
"getZutaten" in eine ArrayList, damit Clients sie verwenden können) zugefügt. Beide Methoden müssen auf
das Local Interface hochgestuft werden.
Anlegen des Webclients
Der Webclient muss die EJB-JARs referenzieren. Dazu in die Eigenschaften des Webmoduls "KuchenZutatWeb"
wechseln und unter "Java-JAR-Abhängigkeiten" das EJB-JAR wählen.
EJB-Verweise festlegen:
Im Webimplementierungsdeskriptor auf die Registerkarte "Verweise" wechseln und lokale Verweise "ejb/Kuchen" und "ejb/Zutat"
auf Kuchen bzw. Zutat zufügen. Das Ergebnis sieht so aus:
Es müssen vier JSP-Seiten "Kuchen.jsp", "KuchenEdit.jsp", "KuchenZutaten.jsp", "KuchenZutatEdit.jsp" zugefügt werden
(Rechtsklick auf "Webmodule" \ "KuchenZutatWeb", im Contextmenü "Neu" -> "Andere..." wählen und in der Auswahlliste links
auf "Web" gehen. Dann rechts "JSP-Seite" auswählen.). Die Einstellungen für "Kuchen.jsp" sieht man im folgenden Screenshot:
Ausführen des Clients
Der Client wird per Rechtsklick und "Auf Server ausführen" gestartet.
Zu beachten ist, dass vorher die Beans auf dem Server laufen. Dazu das EJB-Projekt per Rechtsklick und "Auf Server ausführen"
starten. Wichtig ist, dass in Schritt 2 (nach der Auswahl des Servers) die Option "Tabellen und Datenquellen erstellen" gewählt
wird (zumindest beim ersten Aufruf und nach jeder Änderung).
Die Anwendung ist unter http://localhost:9080/KuchenZutatWeb/Kuchen.jsp zu erreichen.