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
Die verwendete Datenbank heißt hier "KnaufDB"

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.
Erzeugen einer Application (Module)
Der Project Explorer sollte so aussehen:
Project Explorer


Anlegen der Entity Bean

Es wird eine neue Entity Bean angelegt. Dazu im Project Explorer "EJB Projects" -> "KuchenSingleEJB" -> "Deployment Descriptor: KuchenSingleEJB" -> "Entity Beans" wählen und im Contextmenü den Punkt "New" -> "Entity Bean" auswählen.
Es wird der Typ der Bean festgelegt: Es handelt sich um eine Bean mit Container Managed Felder, und zwar nach CMP-Version 2.x. Bean-Name und Package-Name müssen angegeben werden.
Entity Bean, Schritt 1
Im nächsten Schritt wird festgelegt, dass wir hier ein Remote Interface haben wollen. Damit die weiter unten stehenden Erzeugung der Primary Key Werte funktioniert müssen wir ein leider auch ein Local Interface erzeugen !
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 SunAppServer-Beispiel KuchenZutat).
Der Assistent hat bereits ein Primary-Key-Feld "id" vom Typ "java.lang.Integer" für uns erzeugt, dieses verwenden wir:
Entity Bean, Felder (1)
Das einzige Datenfeld unserer Bean ist "Name". Dieses wird ebenfalls zugefügt.
Entity Bean, Felder (2)
Das Ergebnis von Schritt 3 sollte so aussehen:
Entity Bean, Schritt 2
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 im Project Explorer), und unter "Queries" eine neue hinzufügen.
findAll: Schritt 1
Die Query sieht so aus:
select object(o) from KuchenSingle o order by o.name
findAll: Schritt 2
Das Ergebnis sollte so aussehen:
findAll: Schritt 3

Die Logik für das Verwalten des Primary Keys muss implementiert werden:
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 neue hinzufügen.
Wir fügen eine neue Methode namens "ejbSelectMaxId" zu, die den Rückgabetyp "Integer" hat.
Entity Bean, Select-Methode (1)
In Schritt 2 legen wir die Query fest ("select max (o.id) from KuchenSingle o").
Entity Bean, Select-Methode (2)
Automatisch wird in der Bean-Klasse eine abstrakte Methode "ejbSelectMaxId" angelegt.
Hat man beim Erzeugen der Bean keine Local Interfaces aktiviert, dann muss man sich jetzt mit extrem seltsamen Fehlermeldung herumschlagen, einschließlich Compilefehler im generierten Code ! Scheinbar können ejbSelect-Methoden nur in Local Interfaces verwendet werden.

Weitere Nachbearbeitung:
In der Methode "ejbCreate" entfernen wir den Parameter "id" (im Home-Interface nachziehen !). Stattdessen wird die ID mittels "ejbSelectMaxId" geholt und in der Bean gesetzt (zu beachten: bei einer leeren Datenbank liefert das Select NULL zurück):
	try
	{
		Integer intId = this.ejbSelectMaxId(); 
		if (intId == null)
			intId = new Integer (100);
		else
			intId = new Integer (intId.intValue() + 1);
		setId(intId );
	}
	catch (FinderException fex)
	{
		throw new CreateException ("Erzeugung des Kuchens schlug fehl: Holen der NextId per ejbSelectMaxId erzeugte eine FinderException: " + fex.getMessage() );
	} 

Die get-/set-Methoden der Felder sind automatisch in die Home-Interfaces hochgestuft worden (Ausnahme: "getId" und "setId", da ein Client den Primärschlüssel nicht setzen darf).

Die Methode "ejbCreateByName" mit 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. Dies geschieht genauso wie bei Geschäftsmethoden:
ejbCreate auf HomeInterfaces hochstufen
Die vom Assistenten erzeugte Methode "ejbCreate" mit einem Integer-Wert als Parameter wird entfernt.

Jetzt ist es an der Zeit, das Datenbankschema zu erzeugen. Falls wir uns hier auf das automatische Erzeugen der Entwicklungsumgebung verlassen würden, würde er automatisch eine Datenbank namens "TopDownDB" erzeugen. Deshalb jetzt das Datenbankschema manuell erzeugen (siehe Anleitung hier).

Server definieren

Beim Definieren des Servers gibt es einen Unterschied zu den bisherigen Beispielen: wir müssen angeben wie der Server mit den Entity Beans umgehen soll. Zumindest beim ersten Start und bei jedem Deploy nach einer Änderung an der Bean-CMP-Struktur müssen wir die Datenbanktabellen neu erzeugen lassen.
Server (1)

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.
EJB-Referenzen
Hinzufügen einer Java-Klasse "KuchenApplicationClient".
Anwendungsclient: Main-Klasse
Hinzufügen der GUI-Klasse "KuchenFrame" über "New" -> "Other..." -> "Java" -> "Swing" -> "JFrame Visual Class".
Anwendungsclient: Frame-Klasse
Die Frame-Klasse deklarieren:
Anwendungsclient: Frame-Klasse
Hinzufügen einer Java-Klasse "DialogKuchen" über "New" -> "Other..." -> "Java" -> "Swing" -> "JDialog"..
Anwendungsclient: Dialog-Klasse
Die Dialog-Klasse deklarieren:
Anwendungsclient: Dialog-Klasse

Festlegen der Main-Klasse:
Per Doppelklick auf den Deploymentdeskriptor von "KuchenSingleClient" in den "Client Deployment Descriptor" 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.
Anwendungsclient: Main-Klasse
EJB-Verweis festlegen:
Im Clientimplementierungsdeskriptor auf die Registerkarte "References" wechseln und einen Verweis "ejb/KuchenSingle" auf KuchenSingle zufügen.
EJB-Referenzen (Schritt 2)

Ausführen des Clients

Im Menü "Run" den Punkt "Run..." wählen. In der Auswahl "Configurations" unter "WebSphere v6.0 Application Client" eine neue Konfiguration erstellen. Die Einstellungen sollten so aussehen:
Anwendungsclient ausführen
Zu beachten ist, dass vor der Anwendung der EJB-Server gestartet werden sollte.


Version 1.0.1.1, Stand 06.11.2005
Historie:
1.0.0.0 (04.10.2005): Erstellt
1.0.1.0 (29.10.2005): Datenbank im Projekt auf "KnaufDB" geändert.
1.0.1.1 (06.11.2005): Verweis zum Erzeugen einer eigenen Datenbank, Compile-Fehler beim ID-Erzeugen im ejbCreate.