expertenaustausch > comp.lang.* > comp.lang.java

ralf sczepan (22.10.2003, 10:14)
Hallo Group,
ich habe einige Fragen zu CMP und EJB. Ich arbeite mit Jboss 3.2 und
Tomcat 4.1, wobei der Tomcat-Server der Client für den Jboss ist.
Implementieren möchte ich zwei Entity-Beans (Artikel und
Artikelgruppe) die in einer 1:n Beziehung stehen.
Ein Artikel gehört also in eine Artikelgruppe und eine Artikelgruppe
kann mehrere Artikel enthalten. Objektorientiert wäre eine
Artikelgruppe eine Klasse die eine Collection von Artikeln enthält. 
Für den Jboss sieht es so aus.

public Interface Artikelgruppe extends EJBObject{
...
public Collection getArtikel() throws RemoteException;
public void setArtikel(Collection artikels) throws RemoteException;
}

Im Servlet soll folgendes möglich sein

Artikelgruppe gruppe;
Artikel artikel;
// instanzieren der Artikelgruppe und Artikel über das
Remote-Home-Interface
.....

// holen aller Artikel einer Artikelgruppe
Collection gruppenArtikel = gruppe.getArtikel();

// oder einen neuen Artikel einer Artikelgruppe zuweisen.
Collection artikels = gruppe.getArtikel();
artikels.add(artikel);

Laut Docu, Büchern und Tutorials ist der oben gewählte Ansatz ohnehin
falsch, der Client soll ja möglichst nur über SessionBeans auf den
Applicationserver zugreifen.
In dem Buch EJB 2.0 (Addison Wesley) steht sogar "Beziehungen zwischen
Entity-Beans sind nur über den Local-Client-View möglich".

Mein Ansatz sieht so aus:
Das Zuweisen neuer Artikel an eine Warengruppe funktioniert über eine
SessionBean (Verwendung der Local-Interfaces). Diese bietet eine
Methode an, der die ArtikelId und ArtikelgruppenId übergeben werden.
Die Methode übernimmt dann die Zuordnung des Artikels zur
Artikelgruppe. Damit kann ich leben, das funktioniert auch.

Wie sieht es aber aus, wenn der Client gerne alle Artikel einer
bestimmten Warengruppe haben möchte.
In der SessionBean arbeite ich ja nur mit localen Artikeln, die nicht
an den Client durchgreicht werden können. Muss ich die
Artikelattribute einzeln durchreichen?

Wie würde das denn im obigen Beispiel aussehen. Wie stelle ich dem
Client alle Artikel (mit gettern und settern) einer ArtikelGruppe zur
Verfügung.

Danke schonmal

Gruss Ralf
Jens Kutschke (22.10.2003, 10:21)
> Wie sieht es aber aus, wenn der Client gerne alle Artikel einer
> bestimmten Warengruppe haben möchte.
> In der SessionBean arbeite ich ja nur mit localen Artikeln, die nicht
> an den Client durchgreicht werden können. Muss ich die
> Artikelattribute einzeln durchreichen?
> Wie würde das denn im obigen Beispiel aussehen. Wie stelle ich dem
> Client alle Artikel (mit gettern und settern) einer ArtikelGruppe zur
> Verfügung.


Du solltest Dir das Value Object Pattern ansehen:


Zusätzlich können in Deinem Fall auch Data Access Objects sinnvoll sein.
Ebenfalls dort zu finden.

MfG,
Jens
Christian Friedl (22.10.2003, 14:50)
ralf sczepan wrote:
[...]
> Laut Docu, Büchern und Tutorials ist der oben gewählte Ansatz ohnehin
> falsch, der Client soll ja möglichst nur über SessionBeans auf den
> Applicationserver zugreifen.
> In dem Buch EJB 2.0 (Addison Wesley) steht sogar "Beziehungen zwischen
> Entity-Beans sind nur über den Local-Client-View möglich".

Das ist Teil der Spezifikation von EJB 2.0 bzw. CMP.


lg,
Christian
Johann Burkard (22.10.2003, 19:46)
ralf sczepan wrote:

[Schnippschnapp]

> Wie sieht es aber aus, wenn der Client gerne alle Artikel einer
> bestimmten Warengruppe haben möchte.
> In der SessionBean arbeite ich ja nur mit localen Artikeln, die nicht
> an den Client durchgreicht werden können. Muss ich die
> Artikelattribute einzeln durchreichen?


Ich fand dein Posting etwas konfus. Suchst du nach einer Möglichkeit,
1:n-Beziehungen mit Remote-Objekten über das Netzwerk zu verteilen?

Dazu bräuchtest du Remote-Objekte, deren Handles du in eine Collection
steckst und auf denen du beim Herausnehmen getEJBObject() aufrufst. So
in der Art:

public interface Blob extends EJBObject {

public Collection getKekse() throws RemoteException;

}

public class BlobEJB implements EntityBean {

public Collection getKekse() {
Context ctxt = null;

try {
ctxt = new InitialContext();

Object o = ctxt.lookup("ejb/Keks");
KeksHome rh = (KeksHome) PortableRemoteObject.narrow(o, KeksHome.class);

KeksLocalHome lh = (KeksLocalHome) ctxt.lookup("ejb/KeksLocal");
Collection c = lh.getKekse();

Collection out = new HandleArrayList();
Iterator i = c.iterator();
while (i.hasNext()) {
out.add(rh.findByPrimaryKey(((KeksLocal)
i.next()).getPrimaryKey()).getHandle());
}
return out;
}
catch (NamingException ex) {
throw new EJBException(ex);
}
catch (FinderException ex) {
throw new EJBException(ex);
}
catch (RemoteException ex) {
throw new EJBException(ex);
}
finally {
try {
ctxt.close();
}
catch (Exception ex) {}
}
}

}

public class HandleArrayList extends ArrayList {

public Object get(int i) {
Object o = super.get(i);
if (o instanceof Handle) {
return ((Handle) o).getEJBObject();
}
return o;
}

}

Johann, Quickhackend
Marek Lange (22.10.2003, 20:29)
ralf sczepan schrieb:

[..]
> In der SessionBean arbeite ich ja nur mit localen Artikeln, die nicht
> an den Client durchgreicht werden können. Muss ich die
> Artikelattribute einzeln durchreichen?


Die Entity Beans (Artikel, Artikelgruppe) solltest du möglichst mit
local interfaces ausstatten. Wenn du von einem Remote Client darauf
zugreifen willst, geht das nicht, da lokale Beans nur innerhalb der
Virtual Machine benutzt werden können (also im JBoss). Für den Zugriff
benutzt man eine Session Facade, die widerum ein Remote Interface hat.
Wenn du Daten zum CLient schaufeln willst, benutzt du, wie schon vorher
erwähnt, Value Objects. Kannst du mit XDoclet generieren. Diese sind
serialisierbar und können übers Netz übertragen werden.

---------- ---- ------------------ ---- ---------------------
| Client | <--> |RI|-| Session Facade | --> |LI|-| local Entity Bean |
---------- VO ---- ------------------ ---- ---------------------

(RI=Remote Interface, LI=Local Interface, VO=Value Object)

-marek
ralf sczepan (23.10.2003, 12:42)
Johann Burkard <johannburkard> wrote in message

> Ich fand dein Posting etwas konfus. Suchst du nach einer M glichkeit,
> 1:n-Beziehungen mit Remote-Objekten ber das Netzwerk zu verteilen?


Ja, Artikelgruppen enthalten ja mehrere Artikel und diese Collection
mit Artikeln möchte ich in irgend einer Weise dem Client zur Verfügung
stellen.

> public class HandleArrayList extends ArrayList {
> public Object get(int i) {
> Object o = super.get(i);
> if (o instanceof Handle) {
> return ((Handle) o).getEJBObject();

^^^^^^^^^^^^^^ da bekomme ich eine
java.rmi.ServerException Can't find SerialContextProvider

Muss ich einen SerialContext bereitstellen und wie geht das?

> }
> return o;
> }
> }


Danke für die Hilfe
Johann Burkard (23.10.2003, 20:02)
ralf sczepan wrote:
> Johann Burkard <johannburkard> wrote in message
>>Ich fand dein Posting etwas konfus. Suchst du nach einer M glichkeit,
>>1:n-Beziehungen mit Remote-Objekten ber das Netzwerk zu verteilen?

> Ja, Artikelgruppen enthalten ja mehrere Artikel und diese Collection
> mit Artikeln möchte ich in irgend einer Weise dem Client zur Verfügung
> stellen.


Das ist ja legitim, ich wollte nur wissen, ob die Artikel Remote-Objekte
sein sollen oder so etwas DTO-Ähnliches.

>> return ((Handle) o).getEJBObject();

> ^^^^^^^^^^^^^^ da bekomme ich eine
> java.rmi.ServerException Can't find SerialContextProvider


Dann gibt's keine jndi.properties im Classpath, die InitialContext
wissen läßt, welche InitialContextFactory benutzt werden soll.

Was für Software verwendest du denn?

Johann
Ähnliche Themen