# EJB3 in Tomcat. das hat selbst mich erstaunt



## ps (14. Nov 2008)

Wie einige hier vielleicht mittlerweile mitbekommen haben finde ich das neue Entwicklungsmodell von JavaEE 5 und insbesondere EJB3 überaus ansprechend. In meine letzten beiden Projekten konnte ich zum Glück Glassfish einsetzen... nun steht ein Webprojekt an in welchem "nur" Tomcat 5.5 zur verfügung steht.

Da ich nicht auf all die Vorteile verzichten wollte (und Spring mir zu überladen und kompliziert ist - hally byto  ), habe ich mir OpenEJB näher angeschaut.

Ich war wirklich verblüfft... openejb.war deployed, context angesteuert, und "Install" gedrückt. Er legt einige JAR files im Lib Verzeichnis ab. Nach einem Neustart gehts dann sofort los:

Da bereits Features von EJB3.1 implementiert sind kann man seine Session Beans auch in der WAR Datei ablegen. Das heisst man deployed seine Webanwendung wie gewohnt, packt Session Beans mit hinein und alles funktioniert wie erwartet (alle Injections, auch unter Tomcat 5.5).

Die Konfiguration beschränkt sich auf JPA und die jta-datasource in openejb.xml (zu finden in conf/ vom tomcat). Mehr ist nicht nötig, eine Bean mit @Stateless, das Interface mit @Local und man hat eine Session Bean. Alle Annotationen funktionieren (@EJB in Servlets, @PersistenceContext, @Resource, etc in den Beans). 

Ich finds super.. wollte das nur mal erwähnt haben


----------



## Gast (14. Nov 2008)

Wer EJBs in TC anwendet hat viellceicht noch nicht kapiert worum es bei EJBs geht.

JPA und JTA, soso... beides geht ohne EJBs.
Wozu nutzt du denn genau EJBs?


----------



## ps (14. Nov 2008)

Gast hat gesagt.:
			
		

> Wer EJBs in TC anwendet hat viellceicht noch nicht kapiert worum es bei EJBs geht.
> 
> JPA und JTA, soso... beides geht ohne EJBs.
> Wozu nutzt du denn genau EJBs?



Wer so spricht ist vielleicht noch nicht bei EJB3 angekommen. Es ist mir völlig egal ob es auch ohne geht. Der EJB3.1 Container von Glassfish ist kein halbes MB groß. Wenn ich mehr brauche überlege ich mir ob ich ein anderes Enterprise Framework einsetzen möchte (oder den kompletten JavaEE 5/6 Stack benutze). Mittlerweile ist es aber eben so das EJBs so ziemlich die leichtgewichtigste Variante sind.

Warum ich EJBs möchte, bzw. was für Vorteile sie bieten:

- sehr einfaches programmiermodell, sehr wenig "infrastrukturcode". Man spart sich eine Menge im Vergleich zum Fußẃeg.
- Thread safe (man braucht sich nicht mehr ums sync'en kümmern, jeder thread bekommt eine eigene Instanz).
- sehr gute Performance auf Multi Core's. Man braucht nicht manuell parallelisieren... EJBs sind automatisch dafür ausgelegt.
- transaktionen - ist ein aufruf erfolgreich werden alle resourcen synchronisiert.
- testbarkeit ist super
- ich brauche keine zusätzlichen libs in meiner app.
- ich kann mich auf meine anwendung und die business logik konzentrieren

mehr vorteile:
http://www.adam-bien.com/roller/abien/entry/why_i_like_ejb_3


Es ist so... wenn du mir eine einfachere Möglichkeit zeigst das alles zu erreichen, bin ich dabei. Aber solange EJB3 die einfachste (und leichtgewichtigste) Möglichkeit ist... hey. Die Zeiten von EJB2.x sind vorbei


----------



## byte (14. Nov 2008)

Das klingt interessant. Gucke ich mir mal an, wenn ich die Zeit finde.


----------



## ps (15. Nov 2008)

Heute ist dazu auch ein Artikel auf infoq.com erschienen:
-> http://www.infoq.com/news/2008/11/openejb-3.1-release


----------



## Gast (15. Nov 2008)

> - sehr einfaches programmiermodell, sehr wenig "infrastrukturcode". Man spart sich eine Menge im Vergleich zum Fußẃeg.


Wenn du beschreiben würdest was du vorhast, könnte man entscheiden was einfacher bzw. komplexer ist.



> - Thread safe (man braucht sich nicht mehr ums sync'en kümmern, jeder thread bekommt eine eigene Instanz).


Dafür reicht ein new ...() an der richtigen Stelle.



> sehr gute Performance auf Multi Core's. Man braucht nicht manuell parallelisieren... EJBs sind automatisch dafür ausgelegt.


Siehe oben.



> - transaktionen - ist ein aufruf erfolgreich werden alle resourcen synchronisiert.


Du meinst sicher impliziete Transaktionen, kann Vorteil, bei komplexeren Vorhaben aber auch ein Nachteil sein.
Transaktionen hat man schon lange ohne EJBs nutzen können.



> - testbarkeit ist super


Hast viel leichtere Testbarkeit ohne SessionBeans.



> - ich brauche keine zusätzlichen libs in meiner app.


? 
Welche denn?
JSE ist immer dabei, das reicht für die meisten Anwendungen.
Und wenn es man mehr werden sollte, nimmt ein Build tool mit Depedency Management (Maven2, Buckminster, etc. pp.), damit sind libs kein Faktor mehr, egal wieviel oder wie wenig.



> - ich kann mich auf meine anwendung und die business logik konzentrieren


Ach ja?
Was ist mit sogenannten "detached Objects", die machen einem das Leben schwer mit EJB, ja, auch mit EJB3.

EJBs haben ihre Vorteile in bestimmten Szenarien, sollten aber nicht immer und vor allem nicht grundlos verwendet werden, da sie immer zur Komplexität führen.

In einer normalen Java Anwendung (zB. nur mit Tomcat) brauche ich mir keine Sorgen um LazyInit Exceptions zu machen, die gibt es dort nicht, da ich keine detached Objects habe  

Wenn du globale Transaktionen nutzen und skalierbar sein willst, nimmst du eben EJB3, wobei letzteres nicht allein durch EJBs gegeben ist, dazu gehört um einiges mehr.

ps, ich rede hier nicht von Spring vs. EJB3, ich rede von EJB allgemein, sie sind kein allheilmittel, sondern führen immer zu komplexeren Code als eigentlich nötig ist um das Problem für den Fachbereich zu lösen.


----------



## ps (15. Nov 2008)

Gast hat gesagt.:
			
		

> Wenn du beschreiben würdest was du vorhast, könnte man entscheiden was einfacher bzw. komplexer ist.



Ich traue mir durchaus zu das selbst zu entscheiden, aber danke für das Angebot.



> Dafür reicht ein new ...() an der richtigen Stelle.



Das musst du mir erklären. Wie machst du eine Anwendung threadsafe indem du new ...() benutzt?
keine synchronized methoden, keine synchronized blocks?

Ich lerne gerne dazu 



> > sehr gute Performance auf Multi Core's. Man braucht nicht manuell parallelisieren... EJBs sind automatisch dafür ausgelegt.
> 
> 
> Siehe oben.



Du bist mir immer noch eine Erklärung schuldig  Mit new ...() machst du keinen neuen Thread auf... 



> > - ich brauche keine zusätzlichen libs in meiner app.
> 
> 
> ?
> ...



JSE reicht aber in vielen Fällen nicht. Es geht dann weiter mit JPA (EclipseLink, Hibernate oder was auch immer), irgendwas für die Webservices, und evtl. möchte man dann doch noch DI haben und landet bei Spring oder guice.
Die Realworld Webapplikation welche nur mit JSE gebaut wird zeigst du mir bitte 

Build Management... ja. Ich habe lange Maven2 benutzt. Mittlerweile benutze ich wo möglich wieder native IDE Projekte (NetBeans macht das mit ant). Aber das ist ja ein völlig anderes Thema.



> > - ich kann mich auf meine anwendung und die business logik konzentrieren
> 
> 
> Ach ja?
> Was ist mit sogenannten "detached Objects", die machen einem das Leben schwer mit EJB, ja, auch mit EJB3.



Findest du? Ich finde daran eigentlich nichts schwieriges... im Gegenteil. Es ist doch genial das ich im Frontend mit den selben Objekten arbeiten kann welche ich im Backend für die Persistenz benutze. Vor EJB3 musste man dafür DTOs / ValueObjects benutzen. DAS hat einem das Leben schwer gemacht.

Was genau haben detached Objects deiner Meinung nach eigentlich mit EJB zu tun?



> EJBs haben ihre Vorteile in bestimmten Szenarien, sollten aber nicht immer und vor allem nicht grundlos verwendet werden, da sie immer zur Komplexität führen.



Hier muss ich dir widersprechen. Ich finde EJBs durchaus auch für "kleinere" Projekte gut einsetzbar, man zieht damit eine klare Trennlinie zwischen Frontend und Backend. Man sollte sich natürlich überlegen ob diese Trennung überhaupt benötigt wird ;-)



> In einer normalen Java Anwendung (zB. nur mit Tomcat) brauche ich mir keine Sorgen um LazyInit Exceptions zu machen, die gibt es dort nicht, da ich keine detached Objects habe



Das ist richtig... die LazyInit Problematik hat aber damit zu tun das die Objekte über VM Grenzen hinweggeschickt werden. So lange du innerhalb einer VM bleibst hast du damit auch bei EJB keine Probleme. Detached Entities hingegen hast du natürlich auch mit reinem JSE + JPA Provider.



> ps, ich rede hier nicht von Spring vs. EJB3, ich rede von EJB allgemein, sie sind kein allheilmittel, sondern führen immer zu komplexeren Code als eigentlich nötig ist um das Problem für den Fachbereich zu lösen.



Du verallgemeinerst hier doch ein bisschen stark. Das sie kein Allheilmittel sind ist richtig. Das sie nicht immer sinnvoll sind ist auch richtig. Aber das der Code dadurch zwangsläufig immer Komplexer wird ist einfach falsch. Meiner Meinung nach ist eher das Gegenteil der Fall.


----------



## maki (15. Nov 2008)

> Ich traue mir durchaus zu das selbst zu entscheiden, aber danke für das Angebot.


Wie soll man bewerten/diskutieren ob eine API/Archtitektur geeignet ist, ohne die Problemstellung zu kennen?
Oder willst du einfach immer EJBs einsetzen, einfach so? 



> Das musst du mir erklären. Wie machst du eine Anwendung threadsafe indem du new ...() benutzt?
> keine synchronized methoden, keine synchronized blocks?
> 
> Ich lerne gerne dazu icon_smile.gif


In einem Servletcontainer führt jeder Request zu einem neuen Thread (ja, ganz ohne EJBs *g*)

synchronized ist nicht unbedingt die beste Art eine Anwendung threadsicher zu machen, nur wenn es nicht anders geht, viele API (JDBC, etc.) sorgen von selbst dafür dass die richtigen Dinge synchronisiert werden.
Problmatisch ist es, wenn man static benutzt, und dieses Problem gilt auch für EJBs.



> Du bist mir immer noch eine Erklärung schuldig icon_smile.gif Mit new ...() machst du keinen neuen Thread auf...


Siehe oben.



> JSE reicht aber in vielen Fällen nicht. Es geht dann weiter mit JPA (EclipseLink, Hibernate oder was auch immer), irgendwas für die Webservices, und evtl. möchte man dann doch noch DI haben und landet bei Spring oder guice.
> Die Realworld Webapplikation welche nur mit JSE gebaut wird zeigst du mir bitte icon_smile.gif


Auch wieder richtig, Servlets sind schon Teil von JEE.

Was ich meinte war, wenn man sich dafür entscheidet andere JEE APIs zu verwenden, muss dass doch einen Grund haben.



> Findest du? Ich finde daran eigentlich nichts schwieriges... im Gegenteil. Es ist doch genial das ich im Frontend mit den selben Objekten arbeiten kann welche ich im Backend für die Persistenz benutze. Vor EJB3 musste man dafür DTOs / ValueObjects benutzen. DAS hat einem das Leben schwer gemacht.
> 
> Was genau haben detached Objects deiner Meinung nach eigentlich mit EJB zu tun?


Hast mich falsch verstanden.

Detached Objects hat man sobald eine Entity ausserhalb der Session verwendet wird, zB. wenn man sich von einer SessionBean eine Entity liefern lässt, dass hat nix damit zu tun ob EJB oder nicht.

Wenn ich eben alles nur noch im Servletcontainer laufen lasse, habe ich dieses Problem der detached Objects und damit der lazy init Exeptions nicht mehr.



> Hier muss ich dir widersprechen. Ich finde EJBs durchaus auch für "kleinere" Projekte gut einsetzbar, man zieht damit eine klare Trennlinie zwischen Frontend und Backend.* Man sollte sich natürlich überlegen ob diese Trennung überhaupt benötigt wird *icon_wink.gif


Eben, genau das meinte ich.

Ob ich meine "Frontend/Backend" sachen zwischen Servletcontainer und EJBContainer verteile oder "nur" auf packetebene trenne, hängt von der Problemstellung ab 



> Das ist richtig... die LazyInit Problematik hat aber damit zu tun das die Objekte über VM Grenzen hinweggeschickt werden. So lange du innerhalb einer VM bleibst hast du damit auch bei EJB keine Probleme. Detached Entities hingegen hast du natürlich auch mit reinem JSE + JPA Provider.


Nich trichtig, im JBoss zB laufen sowohl Servlet- als auch EJB COntainer in derselben VM, trotzdem habe ich die gleichen Probleme als ob es sich um 2 Physiklische Maschinen handelt.

Und im Tomcat brauche ich das Problem der detached Entites/Objects nicht notwendigerweise zu haben  (auser man macht es wirklich umständlicher als es sein muss )



> Du verallgemeinerst hier doch ein bisschen stark. Das sie kein Allheilmittel sind ist richtig. Das sie nicht immer sinnvoll sind ist auch richtig. Aber das der Code dadurch zwangsläufig immer Komplexer wird ist einfach falsch. Meiner Meinung nach ist eher das Gegenteil der Fall.


Natürlich wird es komplexer wenn ich EJBs verwende, probiers mal ohne 
Klar ist es nciht mehr so brutal wie zu EJB2 Zeiten mit CMP/BMP, aber immer noch mehr Aufwand als ohne, die lazy init exception sei als Beispiel genannt( und leider ist dass das häufigste Problem).


----------



## ps (15. Nov 2008)

maki hat gesagt.:
			
		

> > Ich traue mir durchaus zu das selbst zu entscheiden, aber danke für das Angebot.
> 
> 
> Wie soll man bewerten/diskutieren ob eine API/Archtitektur geeignet ist, ohne die Problemstellung zu kennen?
> Oder willst du einfach immer EJBs einsetzen, einfach so?



Ja, immer. Einfach so ;-)
Nein - im konkreten Fall geht es um ein Webfrontend, teils Flash, teils Formulare. Das Flash wird per Webservice gefüttert. Ausserdem gibts noch eine HTML-Administrationsoberfläche welche wohl ziemlich plain wird, evtl. ein bisschen AJAX Schnickschnack um die powerpoint zu füllen ^^

Kernstück ist das Backend welches dem Frontend die Daten aufbereitet, Aktionen unter bestimmten Voraussetzungen einleitet, etc.

Im Prinzip also eine recht kleine Anwendung... man müsste hier sicherlich kein EJB einsetzen wenn man nicht möchte. Allerdings macht es finde ich einiges einfacher - und auf diesen Komfort möchte ich nicht verzichten. Zumal sich der Tomcat derart leicht aufbohren lässt.



> In einem Servletcontainer führt jeder Request zu einem neuen Thread (ja, ganz ohne EJBs *g*)



Hilfe. Ja, das tut er wohl. Aber dein Servlet ist desshalb dennoch nicht threadsafe. Im Gegenteil... mehrere Requests teilen sich das selbe Servlet. Selbiges gilt auch für Filter. (Viele Webframeworks benutzen Filter anstatt Servlets: Wicket, Struts2)

Aber ich weiß schon was du meinst - wenn du für jeden Request der da im Servlet ankommt ein neues Objektgeflecht hochfährst dann bist du einigermaßen threadsafe.

Wenn ich das so mache habe ich das Verhalten von PHP simuliert: bei jedem Request wird meine Anwendung neu geladen und komplett aus dem Speicher gehauen.



> Detached Objects hat man sobald eine Entity ausserhalb der Session verwendet wird, zB. wenn man sich von einer SessionBean eine Entity liefern lässt, dass hat nix damit zu tun ob EJB oder nicht.



Meinst du HibernateSession? Ich vermute mal das ist der PersistenceContext in JPA?

Der EntityManager detached wenn er den Context verlässt. Ich verstehe nicht was daran problematisch ist?
Wenn ich ein einzelnes oder eine Liste von Entities bekomme dann möchte ich sie in der Regel anzeigen. Wenn ich ein Entity ändere, dann muss ich es sowieso mit em.merge() zurückschreiben. Dabei wird das detached Entity wieder zu einem managed Entity.

Ich wüsste gerade nicht was ich überhaupt mit managed Entities anfangen würde... (ausser innerhalb einer Transaktion oder eines Verarbeitungsschrittes). Für LazyLoading können die Entities AFAIK auch detached sein.. (zumindest bei EclipseLink)



> Wenn ich eben alles nur noch im Servletcontainer laufen lasse, habe ich dieses Problem der detached Objects und damit der lazy init Exeptions nicht mehr.



Ähm - du machst alle Datenbankzugriffe in _einen_ PersistenceContext? Normalerweise holt man sich doch bei Bedarf einen neuen EntityManager (über die EntityManagerFactory). Wenn du nur einen EntityManager hast, kannst du ja auch jeweils immer nur eine Transaktion gleichzeitig offen haben... ?!



> Ob ich meine "Frontend/Backend" sachen zwischen Servletcontainer und EJBContainer verteile oder "nur" auf packetebene trenne, hängt von der Problemstellung ab



Und von meiner Faulheit ;-) Wenn mir EJB infrastrukturcode spart, dann bin ich dabei. und das tut er.


```
EJB.lookup(CrudService.class).delete(myDetachedObject);
```

vs.


```
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
MyObj obj = entityManager.merge(myDetachedObject);
em.remove(obj);
em.getTransaction().commit();
em.close();
```

Ok, das ist nicht ganz fair. Natürlich könnte man das EntityManager gedöns auch im zweiten Beispiel in eine Helperklasse auslagern. Aber darin bleibt es das selbe: EM holen, Transaktion, merge, close, etc. Alles das benötige ich in einer Stateless Bean nicht. Die gesamte Klasse könnte so aussehen:


```
@Stateless
@Local(GenericCrudService.class)
public class GenericCrudServiceBean implements GenericCrudService {
	private final static Logger logger = Logger.getLogger(GenericCrudServiceBean.class.getName());

	@PersistenceContext
	EntityManager em;

	@Override
	public PersistentBean create(PersistentBean t) {
		Date now = new Date();
		t.setCreated(now);
		t.setLastChanged(now);
		this.em.persist(t);
		return t;
	}

	@Override
	public PersistentBean find(Serializable id, Class type) {
		return (PersistentBean) this.em.find(type, id);
	}

	@Override
	public PersistentBean update(PersistentBean t) {
		t.setLastChanged(new Date());
		return this.em.merge(t);

	}

	@Override
	public void delete(PersistentBean t) {
		this.em.merge(t);
		this.em.remove(t);
	}
}
```

Man könnte das natürlich auch mit Generics machen... ich brauchte in dem Fall aber die Zugriffszeiten (und bin zu faul das andere Projekt aufzumachen ^^). Auch für andere Geschichten ist so ein PersistentBean Interface praktisch.



> Nich trichtig, im JBoss zB laufen sowohl Servlet- als auch EJB COntainer in derselben VM, trotzdem habe ich die gleichen Probleme als ob es sich um 2 Physiklische Maschinen handelt.



Auch wenn die Session Bean als @Local markiert ist? Unter glassfish hat man in diesem Fall keinerlei Probleme mit LazyLoading - sogar @Remote macht keine Problem, erst wenn man serialisiert. Aber ich glaube TopLink bzw. jetzt EclipseLink bringt hierfür noch ein bisschen zusätzliche Magie mit.



> Und im Tomcat brauche ich das Problem der detached Entites/Objects nicht notwendigerweise zu haben  (auser man macht es wirklich umständlicher als es sein muss )



Ich verstehe immer noch nicht was an detached Entities so ein großes Problem ist.



> Natürlich wird es komplexer wenn ich EJBs verwende, probiers mal ohne



Hmmm.. vielleicht. Aber auf ein paar Antworten von oben bin ich noch sehr gespannt


----------



## byte (16. Nov 2008)

ps hat gesagt.:
			
		

> Für LazyLoading können die Entities AFAIK auch detached sein.. (zumindest bei EclipseLink)



Das halte ich aber für ein Gerücht. Oder Du verstehst unter DETACHED etwas anderes als ich...

Das ist doch grade das Problem, dass Lazy Loading eben nicht mehr klappt, wenn die Entity detached ist. In einem 0815 Datenmodell fällt das weniger auf. Aber sobald man mal mit komplexen Objektgraphen arbeitet und nicht immer den gesamten Graphen laden will, dann ist das Detachen nicht mehr so trivial.


----------



## ps (16. Nov 2008)

byto hat gesagt.:
			
		

> ps hat gesagt.:
> 
> 
> 
> ...



Also unter TopLink (jetzt EclipseLink) nennt sich das Indirection. Standardmäßig wird "transparent indirection" benutzt, das bedeutet man bekommt davon nichts mit. Die Entities werden mit vendorspezifischem Code "geschmückt", dieser ist allerdings transient und geht verloren sobald das Objekt serialisiert wird.

Die LazyLoading Problematik tritt also zB. dann auf wenn man eine VM verlässt und Remotezugriffe zulässt oder seine Entities in eine Web session packt. Das hat aber alles nichts mit EJB zu tun.
( -> http://download.oracle.com/docs/cd/E12839_01/web.1111/b32441/mapun.htm#CHDEEIBD

Allerdings habe ich in der JPA 2.0 Spec nichts darüber gefunden, es könnte also ein reines EclipseLink feature sein.


----------



## Gast (18. Nov 2008)

> Im Prinzip also eine recht kleine Anwendung... man müsste hier sicherlich kein EJB einsetzen wenn man nicht möchte. Allerdings macht es finde ich einiges einfacher - und auf diesen Komfort möchte ich nicht verzichten. Zumal sich der Tomcat derart leicht aufbohren lässt.


Eben.

Will nicht sagen dass es schlimm ist EJBs so einzusetzen, denke aber dass die persönliche Präferenz in diesem Fall deine Entscheidung stark beeinflusst, was im Prinzip auch richtig ist -> nutze eine technologie die du kennst.
Für jemanden der sich nicht mit EJB3 auskennt aber dafür mit struts reicht struts vollkommen aus, der Code wäre sogar ein bisschen einfacher als deiner und setzt um einiges weniger Wissen voraus.



> Hilfe. Ja, das tut er wohl. Aber dein Servlet ist desshalb dennoch nicht threadsafe. Im Gegenteil... mehrere Requests teilen sich das selbe Servlet. Selbiges gilt auch für Filter. (Viele Webframeworks benutzen Filter anstatt Servlets: Wicket, Struts2)


Mal abgesehen dass ich keine "nackten" Servlets mehr einsetze sondern JSF (früher struts "1"), sind es einfache Grundregeln um ein Servlet es threadsafe zu machen welche du auch einhalten musst, zumal du struts einsetzt.



> Aber ich weiß schon was du meinst - wenn du für jeden Request der da im Servlet ankommt ein neues Objektgeflecht hochfährst dann bist du einigermaßen threadsafe.
> 
> Wenn ich das so mache habe ich das Verhalten von PHP simuliert: bei jedem Request wird meine Anwendung neu geladen und komplett aus dem Speicher gehauen.


Das war es nicht was ich meinte, sondern die "normalen" Techniken für Threadsicheres Programmieren.
lokale vs. Objekt Variablen zB. etc., hat nix mit PHP zu tun bzw. dessen Overhead, den ja schon normale Servlets nicht mehr haben.



> Meinst du HibernateSession? Ich vermute mal das ist der PersistenceContext in JPA?


Ja.



> Ähm - du machst alle Datenbankzugriffe in _einen_ PersistenceContext? Normalerweise holt man sich doch bei Bedarf einen neuen EntityManager (über die EntityManagerFactory). Wenn du nur einen EntityManager hast, kannst du ja auch jeweils immer nur eine Transaktion gleichzeitig offen haben... ?!


Natürlich nicht, aber man kann wenn man alles im TC ohne EJB macht eben immer eine Session offen haben, dadurch gewinnt man auch einiges an performance und erspart sich fetched Queries -> die Entities sind nie detached.



> Ich wüsste gerade nicht was ich überhaupt mit managed Entities anfangen würde... (ausser innerhalb einer Transaktion oder eines Verarbeitungsschrittes). Für LazyLoading können die Entities AFAIK auch detached sein.. (zumindest bei EclipseLink)


Die sog. "transparent indirection" ist im Prinzip eine Alternative zu Proxybasierten indirection wie hibernate sie nutzt, beide funktionieren ausschliesslich nur innerhalb einer Session, der Unterschied liegt eher darin dass man es eben nicht mit Proxyobjekten zu tun hat, ansonsten nehmen die beiden sich nicht viel.


Das Problem ist doch, wenn dein Objekt eine Collection beeinhaltet welche ausserhalb der Session nutzen möchtest, muss diese auch vorher geladen werden, die Norm ist das Lazyloading, welches aber ausserhalb der Session nicht mehr funktioniert.

Entweder du hast alle deine Colections als Eager annotiert, oder der Glassfish macht wirklich Zauberei, oder ich hab etwas sehr wichtiges schlicht verpasst.


```
EJB.lookup(CrudService.class).delete(myDetachedObject);
```
Sorry, aber das sagt mir nix.
Ist EJB eine deiner Klassen, oder habe ich etwas wichtiges in der EJB API übersehen?

Den EM kann man auch ohne EJBs nutzen, in Anwendungen in denen man rein OO entwickelt steckt die Business Logik nicht in Services, sondern den Domainobjekten, u.a. den Entities.
In solchen Anwendungen muss man dafür sorgen, dass die Entites zugriff auf andere Entites (u.a., zB ValueObjects) haben können und trotzdem keine PersistenceExceptions fangen müssen, das geht mit sog. Repositories, ähnlich wie DAOs, aber anstatt CRUD Operationen werden da high level Domänendienste angeboten, auch gehören Repositories zur Domäne, anders als DOAs bzw. der EM, welche zur Persistenzschicht gehören.

In einfacheren ist es nicht verboten die Businesslogik & Persistenzlogik in den Services zu machen, Fowler nennt das "Transaction Script", dabei ist die Businesschicht aber nicht richtig von der Persistenzschicht (bzw. Integrationsschicht) getrennt und die sog. Domänenobjekte sind nicht viel mehr als Datenklassen mit gettern und settern.


----------



## ps (18. Nov 2008)

Gast hat gesagt.:
			
		

> Eben.
> 
> Will nicht sagen dass es schlimm ist EJBs so einzusetzen, denke aber dass die persönliche Präferenz in diesem Fall deine Entscheidung stark beeinflusst, was im Prinzip auch richtig ist -> nutze eine technologie die du kennst.
> Für jemanden der sich nicht mit EJB3 auskennt aber dafür mit struts reicht struts vollkommen aus, der Code wäre sogar ein bisschen einfacher als deiner und setzt um einiges weniger Wissen voraus.



Eben  Es ging mir ja eigentlich auch nur darum das ich sehr beeindruckt war wie einfach man den Tomcat aufbohren kann..



> Das war es nicht was ich meinte, sondern die "normalen" Techniken für Threadsicheres Programmieren.
> lokale vs. Objekt Variablen zB. etc., hat nix mit PHP zu tun bzw. dessen Overhead, den ja schon normale Servlets nicht mehr haben.



Bist du dann aber nicht wieder bei synchronized? Ich wüsste nicht wie man ein Servlet sonst threadsafe machen soll... das selbe Problem habe ich auch bei Actions in Struts(2). Diese werden nicht per request hochgefahren sondern werden gepooled und eine instanz bedient mehrere requests.



> Natürlich nicht, aber man kann wenn man alles im TC ohne EJB macht eben immer eine Session offen haben, dadurch gewinnt man auch einiges an performance und erspart sich fetched Queries -> die Entities sind nie detached.


Das verstehe ich nicht. Sobald ich mir einen neuen EntityManager aus der Factory hole habe ich auch einen neuen Context. Nahc verlassen dieses Contexts werden die Entities detached.



> Die sog. "transparent indirection" ist im Prinzip eine Alternative zu Proxybasierten indirection wie hibernate sie nutzt, beide funktionieren ausschliesslich nur innerhalb einer Session, der Unterschied liegt eher darin dass man es eben nicht mit Proxyobjekten zu tun hat, ansonsten nehmen die beiden sich nicht viel.



Man kann mit EclipseLink auch proxybasiert arbeiten (und es gibt auch noch eine dritte Möglichkeit). Aber ich benutze eigentlich nur die transparent indirection.



> Das Problem ist doch, wenn dein Objekt eine Collection beeinhaltet welche ausserhalb der Session nutzen möchtest, muss diese auch vorher geladen werden, die Norm ist das Lazyloading, welches aber ausserhalb der Session nicht mehr funktioniert.



Ich muss die Collections nur dann vorher laden (idR. mit .size()) wenn ich das Objekt nachher serialisiere... Wenn ich einen EntitiyManager und somit einen PersistenceContext verlasse, hat das keine Auswirkung auf mein LazyLoading. Entities werden laut Spec nach jedem .commit() detached, oder wenn man den Context verlässt. Aber den context verlässt man eigentlich nach jeder transaktion, nach jedem aufruf der business logik.



> Entweder du hast alle deine Colections als Eager annotiert, oder der Glassfish macht wirklich Zauberei, oder ich hab etwas sehr wichtiges schlicht verpasst.



EclipseLink bzw. Toplink Essentials müsste die Zauberei machen. Ich habe aufgrund dieses Threads ein wenig herumprobiert, das LazyLoading hat immer funktioniert ohne mir darüber groß gedanken zu machen. Ausnahme: wenn ich die Entities serialisiert habe.


```
EJB.lookup(CrudService.class).delete(myDetachedObject);
```
Sorry, aber das sagt mir nix.
Ist EJB eine deiner Klassen, oder habe ich etwas wichtiges in der EJB API übersehen?[/quote]

EJB.java ist bei mir nur eine Lookup Klasse welche den Service über JNDI holt.



> Den EM kann man auch ohne EJBs nutzen, in Anwendungen in denen man rein OO entwickelt steckt die Business Logik nicht in Services, sondern den Domainobjekten, u.a. den Entities.



das ist mir bekannt 



> In solchen Anwendungen muss man dafür sorgen, dass die Entites zugriff auf andere Entites (u.a., zB ValueObjects) haben können und trotzdem keine PersistenceExceptions fangen müssen, das geht mit sog. Repositories, ähnlich wie DAOs, aber anstatt CRUD Operationen werden da high level Domänendienste angeboten, auch gehören Repositories zur Domäne, anders als DOAs bzw. der EM, welche zur Persistenzschicht gehören.



idR. möchte ich eigentlich nicht das meine entities etwas über value objects, persistenzschicht oder sonstiges wissen. Gerade bei DDD sollten solche technischen Sachen aus der Business Logic (den Domain Objekten) herausgehalten werden.



> In einfacheren ist es nicht verboten die Businesslogik & Persistenzlogik in den Services zu machen, Fowler nennt das "Transaction Script", dabei ist die Businesschicht aber nicht richtig von der Persistenzschicht (bzw. Integrationsschicht) getrennt und die sog. Domänenobjekte sind nicht viel mehr als Datenklassen mit gettern und settern.



Das ist die herkömmliche Art EJB zu betreiben... was einen zu sehr methodengetriebenen Anwendungen führt. Objektorientierter wird es wenn man die Logik in die Domain Objekte (Entities) packt. Aber wie gesagt, so lange ich die VM nicht verlasse, hatte ich noch nie probleme in einem Entity die enthaltenen Collections oder @OneToOne's anzusteuern. Diese werden dann bei Bedarf aus der DB geholt.


----------



## byte (18. Nov 2008)

ps hat gesagt.:
			
		

> Es ging mir ja eigentlich auch nur darum das ich sehr beeindruckt war wie einfach man den Tomcat aufbohren kann..


Hättest Du Spring mal eine Chance gegeben, dann hättest Du diese Erkenntnis schon lange gemacht. 



> Bist du dann aber nicht wieder bei synchronized? Ich wüsste nicht wie man ein Servlet sonst threadsafe machen soll... das selbe Problem habe ich auch bei Actions in Struts(2). Diese werden nicht per request hochgefahren sondern werden gepooled und eine instanz bedient mehrere requests.


Ein Servlet ist threadsafe, wenn es entweder keine Member hat oder alle Member per ThreadLocal gekapselt sind. Synchronized wäre hingegen fatal.


----------



## ps (18. Nov 2008)

byto hat gesagt.:
			
		

> ps hat gesagt.:
> 
> 
> 
> ...



Mag sein... aber als ich Spring eine Chance geben wollte gab es noch keine Annotationen. Und das viele XML war mir einfach zu unproduktiv.



> Ein Servlet ist threadsafe, wenn es entweder keine Member hat oder alle Member per ThreadLocal gekapselt sind. Synchronized wäre hingegen fatal.



Was meinst du mit Member?
Ein Servlet ist per Definition _nicht_threadsafe, darum musst du dich selbst kümmern.

Zu ThreadLocal: http://www.jguru.com/faq/view.jsp?EID=1015
Aber keine Ahnung ob das noch aktuell ist - dürfte sich aber nicht allzuviel geändert haben.


----------



## tfa (18. Nov 2008)

ps hat gesagt.:
			
		

> Was meinst du mit Member?
> Ein Servlet ist per Definition _nicht_threadsafe, darum musst du dich selbst kümmern.


Eben, und die sicherste Methode wäre, auf Member zu verzichten, oder sie in ThreadLocals zu kapseln. Alles andere wird komplizierter.



> Zu ThreadLocal: http://www.jguru.com/faq/view.jsp?EID=1015
> Aber keine Ahnung ob das noch aktuell ist - dürfte sich aber nicht allzuviel geändert haben.


Da steht nichts zu ThreadLocal, nur zu SingleThreadModel, was wirklich nicht für den produktiven Einsatz taugt.
ThreadLocal ist eine Klasse im Standard-API (ab Java 1.2).


----------



## Gast (18. Nov 2008)

>> Da steht nichts zu ThreadLocal, nur zu SingleThreadModel, was wirklich nicht für den produktiven Einsatz taugt.

Von STM wurde schon immer abgeraten, mitterlweile ist es deprecated.


----------



## byte (18. Nov 2008)

ps hat gesagt.:
			
		

> Was meinst du mit Member?


Member = Objektvariable



> Ein Servlet ist per Definition _nicht_threadsafe, darum musst du dich selbst kümmern.


Ja, eben. Genau darauf zielte mein Post doch ab.
Wenn Du auf Objektvariablen im Servlet verzichtest, dann ist das Servlet zustandslos und somit perse threadsafe. Oder Du kapselst alle Objektvariablen jeweils in einem ThreadLocal. Dann ist der Zustand an die Threads gebunden.
Wie Du siehst gibt es durchaus mehr als das synchronized Schlüsselwort.



> Zu ThreadLocal: http://www.jguru.com/faq/view.jsp?EID=1015
> Aber keine Ahnung ob das noch aktuell ist - dürfte sich aber nicht allzuviel geändert haben.


Das hat überhaupt nichts mit ThreadLocal zu tun.


----------



## ps (19. Nov 2008)

ok, mein fehler. man lernt nie aus


----------

