Beispiel: Container Managed Relationship zweier Entity Beans (IBM WebSphere)
Inhalt:
Anlegen der Application
Anlegen der Entity Bean "Kuchen"
Anlegen der Entity Bean "Zutat"
Nachbearbeitung der KuchenBean
Nachbearbeitung der ZutatBean
Erstellen der 1:n-Relationship
Anlegen des Webclients
Ausführen des Clients
Ein Blick in die Datenbank
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 weitgehend dem Beispiel "KuchenZutat" für den SunAppServer.
Die Deployanleitung bezieht sich auf IBM WebSphere.
Hier gibt es das WebSphere-Projekt zum Download (dies ist ein Project Interchange-Export, die Importanleitung
findet man im Stateless-Beispiel): KuchenZutatExport.zip
Die verwendete Datenbank heißt hier "KnaufDB"
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 Webprojekt.
Das Ergebnis sollte im Project Explorer so aussehen:
Anlegen der Entity Bean "Kuchen"
Es wird eine neue Entity Bean angelegt. Dazu im Project Explorer "EJB Projects" -> "KuchenZutatEJB" ->
"Deployment Descriptor: KuchenZutatEJB" -> "Entity Beans" wählen und im Contextmenü den Punkt "New" -> "Entity Bean" auswählen.
Bean-Name und Package-Name müssen angegeben werden. Beantyp, CMP-Version und Projekt sind bereits
korrekt vorgewählt.
Im nächsten Schritt 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). Dankenswerterweise hat der Assistent bereits ein PrimaryKey-Feld "id" vom
Typ "java.lang.Integer" zugefügt.
Das einzige weitere Datenfeld unserer Bean ist "Name". Dieses wird zugefügt.
Das Ergebnis dieses Schritts 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.
Bean-Name und Package-Name müssen angegeben werden. Beantyp, CMP-Version und Projekt sind bereits
korrekt vorgewählt.
Im nächsten Schritt wird festgelegt, dass wir hier ein Local Interface haben wollen.
In der unteren Liste fügen wir die Container Managed Attribute zu. Das Primary-Key-Feld "id" wurde bereits
vom Assistent erzeugt.
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 dieses Schrittes 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 "Queries"
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 !):
Zuerst wird eine ejbSelect-Methode hinzufügt, um den bisherigen maximalen Primary Key-Wert der Tabelle zu ermitteln.
Dazu zum EJB-Implementierungsdeskriptor der Bean wechseln (Doppelklick auf die Bean in der J2EE-Hierarchie), und unter
"Queries" eine neue hinzufügen.
Wir fügen eine neue Methode namens "ejbSelectMaxId" zu, die den Rückgabetyp "Integer" hat.
Die Query sieht so aus:
select max (o.id) from Kuchen o
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 "ejbHomeGetNextId" abgerufen (diese wiederum greift auf "ejbSelectMaxId"
zu) und in der Bean gesetzt:
this.setId (this.ejbHomeGetNextId() )
Alternativ hätten wir hier auch über das Home-Interface gehen können:
this.setId ( ( (KuchenLocalHome) (this.getEntityContext().getEJBLocalHome())).getNextId() );
"ejbHomeGetNextId" muss auf das Home-Interface hochgestuft werden.
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 im EJB-Implementierungsdeskriptor unter "Queries"
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 !):
Es wird eine ejbSelect-Methode hinzufügt, um den bisherigen maximalen Primary Key-Wert der Tabelle zu ermitteln.
Dazu im EJB-Implementierungsdeskriptor der Bean unter "Queries" eine neue hinzufügen.
Wir fügen eine neue Methode namens "ejbSelectMaxId" zu, die den Rückgabetyp "Integer" hat.
Die Query sieht so aus:
select max (o.id) from Zutat o
Das Ergebnis mit den beiden 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 "ejbHomeGetNextId" abgerufen
(diese wiederum greift auf "ejbSelectMaxId" zu) und in der Bean gesetzt:
this.setId (this.ejbHomeGetNextId() )
"ejbHomeGetNextId" muss auf das Home-Interface hochgestuft werden.
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-Deploymentdeskriptor wählt man die Kuchen-Bean und geht zu "Beziehungen".
Man klickt auf "Add". Im etwas verwirrenden Assistenten wählen wir links die Kuchen-Bean aus, rechts die
ZutatBean.
Bei der ZutatBean ändern wir den Rollennamen von "zutat" auf "zutaten" (so soll unsere abstrakte Property heißen),
wählen als "Multiplicity" "0..*" und setzen in dem Kasten "Role name" die Checkbox "Cascade delete".
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.
Achtung, Bug: Beim nachträglichen Öffnen des Dialogs kann es
sein dass man die EJB-Relationship zerstört (siehe hier).
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 Dynamic Web Projects "KuchenZutatWeb"
wechseln und unter "Java JAR Dependencies" das EJB-JAR wählen.
EJB-Verweise festlegen:
Im Webimplementierungsdeskriptor auf die Registerkarte "References" 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 "Dynamic Web Projects" -> "KuchenZutatWeb", im Contextmenü "New" -> "JSP File" wä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 "Run" -> "Run on Server..."
starten. Wichtig ist, dass in Schritt 3 (nach der Auswahl des Servers und der auszuführenden Enterprise Application) 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.
Ein Blick in die Datenbank
Mittels des Tools Cview können wir einen Blick in die Datenbank werfen.
Die Tabelle KUCHEN sieht so aus:
Die Tabelle ZUTAT sieht so aus:
Man beachte das zusätzliche erzeugte Feld "KUCHEN_ID" mit dem Foreign Key auf den Kuchen. Der zugehörige Foreign Key
heißt im Beispiel "C6103860".
Version 1.0.1.3, Stand 06.12.2005
Historie:
1.0.0.0 (12.10.2005): Erstellt
1.0.1.0 (29.10.2005): Datenbank im Projekt auf "KnaufDB" geändert.
1.0.1.1 (10.11.2005): Code in KuchenZutat.jsp aufgeräumt, Verweis auf Bug mit EJB-Relationships.
1.0.1.2 (17.11.2005): Alle ejbCreate-Methoden geben jetzt (gemäß EJB-Spezifikation) null
zurück.
1.0.1.3 (06.12.2005): Dateiname für Bildreferenz korrigiert.