Beispiel: Container Managed Relationships


Beispiel für zwei Container Managed Entity Beans, die in einer Container Managed Relationship (CRM) stehen, und auf die per Webclient zugegriffen wird.

Aufbau des Beispieles


Mittels einer Entity Bean werden Objekte vom Typ "Kuchen" abgebildet. Ein Kuchen besteht aus den Properties "ID" und "Name". Die ID ist der Unique Key der Bean und wird in diesem Beispiel nicht vom Container verwaltet, sondern in der Beanklasse erzeugt.
Mittels einer zweiten Entity Bean werden Objekte vom Typ "KuchenZutat" abgebildet. Ein Kuchen besteht aus 0 bis n Zutaten. Eine Zutat besteht aus den Properties "ID", "Name" und "Menge". Die ID ist der Unique Key der Bean und wird in der Beanklasse erzeugt.

Besonderheit dieses Beispiels: da die Relationship vom Container verwaltet wird, müssen beide Beans im selben Container laufen, d.h. Zugriff kann nur über Local-Interfaces erfolgen.

Bestandteile:
a) Entity-Bean-Klasse für ein Objekt "Kuchen" mit Local-Interfaces.
a) Entity-Bean-Klasse für ein Objekt "Zutat" mit Local-Interfaces.
c) Web Client.


Quellcode

In diesem Beispiel wird ein Dynamic Web Project namens "KuchenZutat" verwendet.
Hier gibt es den Code als Export (siehe Anleitung zum Importieren eines Java Projects) KuchenZutatExport.zip.
Hier steckt die EAR-Datei des Deploytools: KuchenZutat.ear

Deploy der Entity Bean "Kuchen"

Schritt 1: Einstellungen siehe Screenshot.
Kuchen Bean (Schritt 1)
Zu beachten: auch die Dateien der Zutat-Bean werden dem JAR zugefügt.
Schritt 2: Bean-Klasse sowie die Local-Interfaces auswählen.
Kuchen Bean (Schritt 2)
Schritt 3: Auswählen der persistenten Datenbankfelder.
Die Felder "ID" und "Name" sollen vom Container verwaltet werden (NICHT aber "Zutaten", die Collection der Zutaten). Der Primary Key ist eines der bestehenden Felder, nämlich "ID".
Kuchen Bean (Schritt 3)
Schritt 3a: Von Schritt 3 aus Deklarieren der Finder.
Diese Anwendung enthält neben der "findAll"-Methode ohne weitere WHERE-Bedingungen eine Select-Methode. Die Query für "findAll" sieht so aus:
select Object(k) from KuchenBean k order by k.name
Wichtig hierbei: Der "Abstract Schema Name" aus Schritt 3 muss genau so in der Finder-Methode verwendet werden.
Kuchen Bean (Finder)

Die Query für die Select-Methode "ejbSelectMaxId" sieht so aus:
select max (k.id) from KuchenBean k
Rechts unten in der Combobox "Returns EJBs of type" wird "None" gewählt, da hier Integer-Werte geliefert werden. Kuchen Bean (Select)

Nachbearbeitung:
Nach dem Anlegen der Bean MÜSSEN die Datenbankfeld-Informationen erzeugt werden (siehe Anleitung beim vorherigen Beispiel). Das Ergebnis sollte so aussehen:
Kuchen Bean (Database Mappings)

Deploy der Entity Bean "Zutat"

SChritt 1: Dem bestehenden JAR wird eine weitere Bean zugefügt, d.h. es sind keine weiteren Klassen zuzufügen.
Schritt 2: Bean-Klasse sowie die Local-Interfaces auswählen.
Zutat Bean (Schritt 2)
Schritt 3: Auswählen der persistenten Datenbankfelder.
Die Felder "ID", "ZutatName" und "Menge" sollen vom Container verwaltet werden (NICHT aber "Kuchen", die Referenz auf den Kuchen, zu dem die Zutat gehört). Der Primary Key ist eines der bestehenden Felder, nämlich "ID".
Zutat Bean (Schritt 3)
Schritt 3a: Von Schritt 3 aus Deklarieren der Finder.
Diese Anwendung enthält neben der "findAll"-Methode (die eigentlich nicht nötig wäre, da wir nur Zutaten eines Kuchens verwenden) ohne weitere WHERE-Bedingungen eine Select-Methode. Die Query für "findAll" sieht so aus:
select Object(z) from ZutatBean z order by z.zutatName
Zutat Bean (Finder)

Die Query für die Select-Methode "ejbSelectMaxId" sieht so aus:
select max (z.id) from ZutatBean z
Rechts unten in der Combobox "Returns EJBs of type" wird "None" gewählt, da hier Integer-Werte geliefert werden. Zutat Bean (Select)

Nachbearbeitung:
Nach dem Anlegen der Bean MÜSSEN die Datenbankfeld-Informationen erzeugt werden (siehe Anleitung beim vorherigen Beispiel). Das Ergebnis sollte so aussehen:
Zutat Bean (Database Mappings)
Hinweis: das Feld "kuchen" wird so erst nach dem nächsten Schritt, dem Erstellen der Relationship, auftauchen.

Erstellen der Container managed relationship

Das Bean-JAR auswählen und auf den Karteireiter "Relationships" wechseln. Dort auf "Add" klicken.
Relationships

Eine "One-to-Many"-Relationship hinzufügen, wobei als Bean A die KuchenBean gewählt wird, auf der "Many"-Seite steht die ZutatBean. Die KuchenBean wird über das Feld "zutaten" mit einer Collection von n ZutatBeans verknüpft. Umgekehrt erhält man durch Abrufen der Property "kuchen" der ZutatBean eine KuchenBean.
Beim Löschen eines Kuchens sollen alle Zutaten gelöscht werden.
Relationships erzeugen
ACHTUNG, Bug: Nach dem Anlegen der Relationships gab es beim Deploy eine Fehlermeldung ("

Deploy des Web Clients

Es wird hier ein Webclient verwendet, da die beiden Beans wegen der Relationship im gleichen Container laufen müssen und deshalb kein Client mittels Remote-Interfaces auf diese Beans zugreifen darf. (Eine Lösung wäre hier eine Session-Bean als Fassade für den Zugriff).
Schritt 1: Hinzufügen der JSP-Seiten und der Local-Interfaces (Screenshot ist zusammengestückelt, um alle Dateien zu zeigen)
Deploy des Web Clients
Anschließend hinzufügen der vier JSPs.

Nachbearbeitung:
Festlegen der Context-Root: kuchenzutat
Folgende EJB-Referenzen hinzufügen:
"ejb/Kuchen" referenziert "com.knauf.ejb.kuchenzutat.LocalKuchenHome" und "com.knauf.ejb.kuchenzutat.LocalKuchen".
"ejb/Zutat" referenziert "com.knauf.ejb.kuchenzutat.LocalZutatHome" und "com.knauf.ejb.kuchenzutat.LocalZutat".


Vor dem Deploy muss der ApplicationServer sowie die PointBase-Datenbank gestartet sein !

Erzeugte Datenbanktabelle

Im Pointbase-Tool sieht die erzeugte Kuchen-Datenbanktabelle so aus:
Datenbank
Die Zutat-Tabelle sieht so aus:
Datenbank
Man erkennt das vom Container automatisch erzeugte Foreign-Key-Feld, mit dem die KuchenBean-Tabelle referenziert wird.



Version 1.0.1.2, Stand 17.11.2005
Historie:
1.0.0.0 (10.10.2005): Erstellt
1.0.1.1 (10.11.2005): Code in diversen JSP aufgeräumt.
1.0.1.2 (17.11.2005): Alle ejbCreate-Methoden geben jetzt (gemäß EJB-Spezifikation) null zurück.