Beispiel: Einfache Container Managed Entity Bean (IBM WebSphere)
Beispiel für eine Container Managed Entity Bean, auf die per Applicationclient zugegriffen wird.
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): KuchenExport.zip
Aufbau des Beispieles
a) Entity Bean-Klasse mit Remote-Interfaces.
b) Application Client
Anlegen der Application
Ein Unternehmensanwendungsprojekt mit dem Namen "KuchenSingle" 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
Es wird eine neue Entity Bean angelegt. Dazu in der J2EE-Hierarchie "EJB-Module" -> "KuchenSingleEJB" ->
"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 Remote Interface haben wollen (den im Default
gesetzten Haken bei "Local Interface" entfernen). In der unteren Liste fügen wir die Container Managed
Attribute zu.
ACHTUNG: IBM WebSphere kennt keine automatisch generierten Primary Keys !
Zitat aus der Hilfe:
Unknown primary key is not supported
The EJB tooling currently does not support the Unknown primary key definition described
in the EJB 2.0 specification. The workaround is to define a specific primary key class.
Aus diesem Grund können wir das Beispiel "Kuchen" nicht eins zu eins vom Sun AppServer übernehmen
und müssen den Primary Key manuell erzeugen (siehe Beispiel KuchenZutat).
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.
Nachbearbeitung:
Die Methode "findAll" muss implementiert werden. Dazu zum EJB-Implementierungsdeskriptor der Bean wechseln (Doppelklick auf die Bean in
der J2EE-Hierarchie), und unter "Abfragen" eine neue hinzufügen.
Die Query sieht so aus:
select object(o) from KuchenSingle o order by o.name
Das Ergebnis sollte so aussehen:
Die Logik für das Verwalten des Primary Keys muss implementiert werden:
ACHTUNG: Das folgende funktioniert nicht, da WebSphere scheinbar zu doof ist !
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 "Abfragen" eine hinzufügen.
Wir fügen eine neue Methode namens "ejbSelectMaxId" zu, die den Rückgabetyp "Integer" hat.
In Schritt 2 legen wir die Query fest ("select max (o.id) from KuchenSingle o").
Automatisch wird in der Bean-Klasse eine abstrakte Methode "ejbSelectMaxId" angelegt.
Das Ergebnis dieses Vorgehens sieht man beim Deploy:
Würgaround:
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 Select-Methode.
Die Finder-Methode hat den Namen "findByMaxId", sie steckt im Remote-Interface, und hat als
Rückgabewert eine einzelne KuchenSingle-Bean.
Die Query sieht so aus:
select object(o) from KuchenSingle o where o.id in (select max (oInner.id) from KuchenSingle 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 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 get-/set-Methoden der Felder müssen noch in das Remote-Interface hochgestuft werden
(Ausnahme: "setId", da ein Client den Primärschlüssel nicht setzen darf).
Die Methode "ejbCreateByName" (Rückgabewert: Integer !) muss zugefügt werden. Natürlich muss auch "ejbPostCreateByName"
implementiert werden. Diese neue Create-Methode muss auf das Home-Interface hochgestuft werden.
Anlegen des Anwendungsclients
Der Anwendungsclient muss die EJB-JARs referenzieren. Dazu in die Eigenschaften des "KuchenSingleApplicationClient"
wechseln und unter "Java-JAR-Abhängigkeiten" das EJB-JAR wählen.
Hinzufügen einer Java-Klasse "KuchenApplicationClient".
Hinzufügen einer Java-Klasse "KuchenFrame".
Hinzufügen einer Java-Klasse "DialogKuchen".
Festlegen der Main-Klasse:
Per Doppelklick auf "KuchenSingleApplicationClient" in den "Clientimplementierungsdeskriptor"
des Clients wechseln. Unter "Hauptklasse" klickt man auf "Bearbeiten" und gelangt in den
"Editor für JAR-Abhängigkeit". Unter "Hauptklasse" wird die Klasse "KuchenApplicationClient" gewählt.
EJB-Verweis festlegen:
Im Clientimplementierungsdeskriptor auf die Registerkarte "Verweise" wechseln und einen Verweis "ejb/KuchenSingle"
auf KuchenSingle zufügen.
Ausführen des Clients
Im Menü "Ausführen" den Punkt "Ausführen..." wählen.
In der Auswahl "Konfigurationen" unter "WebSphere v5.1 Anwendungsclient" eine neue Konfiguration erstellen.
Die Einstellungen sollten so aussehen:
Zu beachten ist, dass vor der Anwendung der EJB-Server gestartet werden sollte (im Dialog "Ausführen" unter "Server" zu finden,
im Beispiel ist dies die "WebSphere v5.1 Testumgebung").