ekkes corner - ekkes ecke
ekkes corner - ekkes ecke

HowTo Build an OSGI Enterprise Server: Entity- Und EJB- Bundles
Dienstag, 11. November 2008
Dieser Teil der Blog - Serie „HowTo build an OSGI Enterporise Server“ beschäftigt sich mit den Bundles, die wir dem EasyBeans EJB3 Container zur Verfügung stellen. Das nächste Kapitel „EJB3 Container“ zeigt dann, wie wir mit Hilfe eines ServiceTrackers den (die) EJB3 Container initialisieren und starten.
Entities und EJBs in Bundles aufteilen
Kenntnisse über EJB3 und Annotations werden vorausgesetzt zum Verständnis. Die hier vorgestellte Struktur ist nur ein Beispiel und kann auch anders implementiert werden. Ebenso kann anstelle von Hibernate auch Eclipse Link als JPA Provider eingesetzt werden - EasyBeans unterstützt beides.
Folgende Bundle - Typen unterscheiden wir:
•Entity - Bundles
•EJB - Bundles
•PersistenceContext - Bundles
•Business Interface - Bundles

Entity - Bundles
@Entity, @Embeddable
Wir können beliebig viele Entity - Bundles nutzen - z.B. vertikal nach Businessbereichen untergliedert. Die Entity - Bundles werden auch vom Rich Client benötigt, daher sollten Dependencies, die nur für den Einsatz im Server benötigt werden, immer optional sein.
EJB - Bundles
@Stateless und @Stateful Beans, die je nach Anforderung die Business - Interfaces (@Local, @Remote) implementieren.
Diese Bundles haben Abhängigkeiten zu den Entity - Bundles und den implementierten Business - Interface - Bundles.
Andere EJBs aus den PersistenceContext - Bundles können injiziert werden:
@EJB(mappedName) Business - Interface
Die EJB - Bundles werden am Rich Client nicht benötigt.
Hinweis: mappedName muss derzeit verwandt werden, da EZB die Business - Interfaces nicht den EJBs zuordnen kann, wenn diese in getrennten Bundles liegen (JIRA EZB-322)
PersistenceContext - Bundles
@Stateless Beans, die einen PersistenceContext (EntityManager) enthalten und je nach Anforderung Business - Interfaces (@Local, @Remote) implementieren.
Mit @PersistenceContext(unit-name) wird der Bezug zur Persistence - Unit hergestellt.
Jedes PersistenceContext - Bundle hat eine persistence.xml mit Angabe der persistence-unit, sowie der jta-data-source.
PersistenceContext - Bundles importieren die Packages der beteiligten Entities und der implementierten Business - Interfaces.
Die PersistenceContext - Bundles werden am Client nicht benötigt.
Hinweise:
1.Alle EJB, die zu einer peristence-unit gehören, müssen derzeit in EINEM Bundle enthalten sein. (JIRA EZB-294)
2.Die Beans müssen einen mappedName zugewiesen bekommen: @Stateless(mappedName), da sie sonst aufgrund eines Fehlers (JIRA EZB-322) beim Injizieren mit @EJB nicht gefunden werden.
3.In der persistence.xml müssen mit class alle Entity- und Embeddable gelistet werden. EasyBeans sollte diese aufgrund der Annotations finden, was aber derzeit - wenn Entities und EJBs in verschiedenen Bundles liegen - noch nicht erfolgt
Business Interface - Bundles
@Local, @Remote
Die Business - Interface - Bundles können je nach Anforderung beliebig aufgeteilt und strukturiert werden, z.B. nach Businessbereichen zusammengefasst.
Diese Bundles werden auch auf dem Rich Client eingesetzt.
EasyBeans Konfiguration
EasyBeans benötigt einige Konfigurationsdaten, die wir z.B. beim starten einer OSGI Framework Konfiguration als VM arguments übergeben:
-Dorg.ow2.easybeans.osgi.conf.dir=${workspace_loc}/config/easybeans/config
In dem config Verzeichnis muss die easybeans.xml vorhanden sein.
Die easybeans.xml enthält jdbcpool jndiName Eintragungen für jede Data - Source. Diese Werte sind identisch mit der jta-data-source, die der Persistence Unit in der persistence.xml der PersistenceContext - Bundles zugewiesen ist.

Hinweis: Die EasyBeans JDBCPool - Komponente muss erst alle Data - Sources registriert haben, bevor die PersistenceContext - Bundles gestartet werden dürfen. s.a. Kapitel „EJB3 Container“ -
openArchitectureWare - Helfer in allen Notlagen
Dieses Projekt ist modellgetrieben - die Details werden in einer anderen Blog Serie beschrieben. Hier nur ein paar kleine Details die zeigen, warum ich openArchitectureWare in keinem Projekt mehr missen möchte.
EasyBeans sollte alle @Entity und @Embeddable automatisch über die Annotation erkennen - dies ist aber über Bundlegrenzen derzeit nicht möglich, also müssen alle @Entity und @Embeddable - Klassen in der persistence.xml gelistet werden - in meinem ERP Projekt sind das 800 Klassen und das Datenmodell ist natürlich nicht statisch, sondern verändert sich ständig durch neue Requirements.
Um diese Ausgabe in die persistence.xml zu bekommen, benötigen wir aber nur ein paar Zeilen:

und schon wird alles generiert und entspricht dem aktuellen Datenmodell:

Ein anderes Beispiel: EasyBeans sollte @EJB MyBusinessInterface korrekt injizieren können. Aufgrund eines Fehlers ist dies aber derzeit nicht möglich, wenn die Business Interfaces in einem eigenen Bundle liegen und wir benötigen das @EJB.mappedName Attribut.
Also einfach im XPand - Template bei der Bean das Attribut einfügen:

und im Business Interface:

Dann erhalten alle Beans automatisch das mappedName Property, die Business Interfaces eine Konstante mit dem mappedName und beim Injizieren geths einfach:
@EJB(mappedName = MyInterface.EZB_MAPPED_NAME) MyInterface mi = null;
Schnell eingebaut und generiert oder rückgängig gemacht nach Bugfixing.
Das sind positive Nebeneffekte von modellgetriebener Entwicklung, wo sogar das Programmieren von Workarounds aufgrund von Bugs Spass macht ;-)
Übrigens: das ganze komplexe ERP - Projekt wäre mir ohne oAW nicht möglich gewesen, zu realisieren. Näheres dazu gibt es dann in einer anderen Blog Serie.
Den Index der Blogserie finden Sie hier - Diskussionen bitte in der englischen Ausgabe.