# DAO stateless oder stateful?



## membersound (31. Jan 2012)

Hallo,

ich überlege gerade, wie ich meiner WebApp (auf JBoss 7) eine paar DAOs verpasse:

a) @Stateless mit banaler CRUD Funktionalität + und einem @Stateful @RequestScoped DAO Manager, der entsprechend die DAOs aufruft.

b) die DAOs direkt @Stateful @RequestScoped machen und mir eine (möglicherweise unnötige) Schicht sparen. Oft macht der Dao-Manager ja doch nicht viel mehr, als die Daos aufzurufen?


Was sagen die, die da schon mehr Erfahrung haben?
Danke


----------



## Sym (1. Feb 2012)

Ich würde eine EJBs Schicht für die Businesslogik als Stateless Beans implementieren.

Ich bin mir ziemlich sicher, dass Du Probleme mit dem Aktualisieren des Entitymanagers bekommst, wenn Du Stateful Beans nutzt. Was für einen Vorteil versprichst Du Dir davon?


----------



## Sanix (1. Feb 2012)

Für was brauchst du den State?


----------



## Andgalf (1. Feb 2012)

Sym hat gesagt.:


> Ich bin mir ziemlich sicher, dass Du Probleme mit dem Aktualisieren des Entitymanagers bekommst, wenn Du Stateful Beans nutzt



Warum das?? Dafür gibt es doch den ExtendendPersistenceContext. Meiner Erfahrung nach kann es ganz hiflreich sein Statefull Beans mit dem ExtendendPersistenceContext zu verwenden um das lästige Lazy-Initialisation Problem zu umgehen.


----------



## Gast2 (1. Feb 2012)

Sym hat gesagt.:


> Ich würde eine EJBs Schicht für die Businesslogik als Stateless Beans implementieren.
> 
> Ich bin mir ziemlich sicher, dass Du Probleme mit dem Aktualisieren des Entitymanagers bekommst, wenn Du Stateful Beans nutzt. Was für einen Vorteil versprichst Du Dir davon?



Kommt auf den Context an für einen Warenkorb sind Stateful Beans nützlich.
Aber DAOs Stateful zu machen, halte ich für unsinnig, weil ein DAO keine Daten hält, außerdem ist der EntityManager ja schon Teil der DAO Schicht zumindest für die CRUD Operationen


----------



## Sym (1. Feb 2012)

Andgalf hat gesagt.:


> Warum das?? Dafür gibt es doch den ExtendendPersistenceContext. Meiner Erfahrung nach kann es ganz hiflreich sein Statefull Beans mit dem ExtendendPersistenceContext zu verwenden um das lästige Lazy-Initialisation Problem zu umgehen.


Ja, aber das muss man wissen. Deshalb war ich mir ja auch nur ziemlich sicher. 

Ich habe das jedenfalls noch nicht als Ansatz gesehen, um Lazy-Initialisation-Probleme zu lösen.


SirWayne hat gesagt.:


> Kommt auf den Context an für einen Warenkorb sind Stateful Beans nützlich.
> Aber DAOs Stateful zu machen, halte ich für unsinnig, weil ein DAO keine Daten hält, außerdem ist der EntityManager ja schon Teil der DAO Schicht zumindest für die CRUD Operationen


Ja klar, haben Stateful Beans einen Sinn. Aber der Frage des TEs nach zu urteilen, empfand ich das an dieser Stelle als unsinnig.

Eigentlich wollte ich auch nur wissen, was für einen Vorteil der TE in einem Stateful sieht - auch damit ich besser verstehe, was genau er überhaupt möchte.


----------



## Gast2 (1. Feb 2012)

Sym hat gesagt.:


> Ja, aber das muss man wissen. Deshalb war ich mir ja auch nur ziemlich sicher.
> 
> Ich habe das jedenfalls noch nicht als Ansatz gesehen, um Lazy-Initialisation-Probleme zu lösen.



Der ExtendendPersistenceContext ist für eine long running session da, damit du in der Session immer wieder den gleichen em bekommst..

Warum der Lazy-Initialisation-Probleme lösen soll kann ich dir allerdings nicht sagen, ist mir auch neu...


----------



## Andgalf (1. Feb 2012)

SirWayne hat gesagt.:


> Der ExtendendPersistenceContext ist für eine long running session da, damit du in der Session immer wieder den gleichen em bekommst..
> 
> Warum der Lazy-Initialisation-Probleme lösen soll kann ich dir allerdings nicht sagen, ist mir auch neu...



Na ja .... die  lazyInitException bekommst man genau dann, wenn man auf eine Collection zugreift, welche von Hibernate bzw. JPA geproxied wurde aber die Session schon geschlossen ist.

Von daher kann man mit dem Ansatz SFSB und ExtendedPersistenceContext dafür sorgen, dass die Session nicht vorzeitig geschlossen wird.


----------



## membersound (1. Feb 2012)

Angenommen, wir haben so eine grobe "soziales Netzwerk" App: Es gibt Benutzer, jeder Benutzer ist bestimmten Gruppen zugeordnet, jeder Benutzer kann Nachrichten an andere Benutzer schreiben.

Um DAOs komme ich ja nicht herum, die brauch ich so oder so für den DB-Zugriff.
Die Frage ist jetzt: Bekommen die Daos jetzt noch einen Stateful Dao-Manager? Oder greif ich aus dem View (JSF) direkt auf die (stateless) Daos zu?


----------



## Gast2 (1. Feb 2012)

Andgalf hat gesagt.:


> Na ja .... die  lazyInitException bekommst man genau dann, wenn man auf eine Collection zugreift, welche von Hibernate bzw. JPA geproxied wurde aber die Session schon geschlossen ist.
> 
> Von daher kann man mit dem Ansatz SFSB und ExtendedPersistenceContext dafür sorgen, dass die Session nicht vorzeitig geschlossen wird.



Naja so allgemein kann man das nicht sagen, wenn du eine Desktopanwendung hast, hast du immer Probleme mit LazyLoading...



membersound hat gesagt.:


> Angenommen, wir haben so eine grobe "soziales Netzwerk" App: Es gibt Benutzer, jeder Benutzer ist bestimmten Gruppen zugeordnet, jeder Benutzer kann Nachrichten an andere Benutzer schreiben.
> 
> Um DAOs komme ich ja nicht herum, die brauch ich so oder so für den DB-Zugriff.
> Die Frage ist jetzt: Bekommen die Daos jetzt noch einen Stateful Dao-Manager? Oder greif ich aus dem View (JSF) direkt auf die (stateless) Daos zu?



Du benötigst eine BusinessLogik Schicht. Eine DAO Schicht muss nicht unbedingt notwendig sein, es kann auch der EntityManager reichen, der wie gesagt im Grunde genommen ein DAO ist.

Was soll den der DAOManager machen?


----------



## DerFeivel (1. Feb 2012)

@TE:


Irgendwie wird mir aus deinem Post nicht ganz klar, was du vorhast  bzw. welches Problem du zu lösen versuchst. 


Ein DAO kapselt dir die Zugriffe auf eine Datenquelle und bietet dir eine vereinfachte, abstrahierte(ohne technische Details des Quellenzugriffs) Schnittstelle zu deiner Datenquelle. Wozu muss da das Ganze zustandsbehaftet sein? 


BTW: Welchen Sinn erfüllt dein DAOManager?


----------



## Andgalf (1. Feb 2012)

SirWayne hat gesagt.:


> Naja so allgemein kann man das nicht sagen, wenn du eine Desktopanwendung hast, hast du immer Probleme mit LazyLoading...



Stimmt natürlich, dass es sich um eine Web-Anwendung handelt hatte ich jetzt i-wie vorrausgesetzt


----------



## membersound (1. Feb 2012)

Ich hatte mir das so vorgestellt, dass der DAOmanager den Zugriff für den JSF-View bereitstellt. Also Methoden + Felder, die ich dann über EL nutzen kann. Nach dem MVC Prinzip wär dieser Manager dann quasi mein Controller.

Womit ich aber wieder bei meiner Eingangsfrage wäre, ob das sinnvoll oder notwendig ist? Oder ob ich das auch direkt mit den Daos realisieren kann? Also dass die Daos quasi Data-Access + Controller in einem sind?



DerFeivel hat gesagt.:


> Irgendwie wird mir aus deinem Post nicht ganz klar, was du vorhast  bzw. welches Problem du zu lösen versuchst.


Das weiß ich auch selbst noch nicht so genau. Mir geht es eher darum Aufbau+Design von (business) Webapps zu verstehen. Und natürlich dann entsprechend anzuwenden.


----------



## DerFeivel (1. Feb 2012)

membersound hat gesagt.:


> Ich hatte mir das so vorgestellt, dass der DAOmanager den Zugriff für den JSF-View bereitstellt. Also Methoden + Felder, die ich dann über EL nutzen kann. Nach dem MVC Prinzip wär dieser Manager dann quasi mein Controller.
> 
> Womit ich aber wieder bei meiner Eingangsfrage wäre, ob das sinnvoll oder notwendig ist? Oder ob ich das auch direkt mit den Daos realisieren kann? Also dass die Daos quasi Data-Access + Controller in einem sind?
> 
> ...




Für solche Fragen lohnt sich als Einstieg: 

Clean Code Developer - Clean Code Developer

Mir würde gerade das Single Responsibility Principle einfallen. Also Trennen in Controller und Data-Access.
Ansonsten enthalten dann deine DAOs ja Methoden, welche ihrer Verantwortung (Datenzugriff) als DAO nicht entsprechen. Darüber hinaus hast du dann auch 2 Mögliche Auslöser für Veränderungen an den Klassen. Einmal wenn ein neues Feld o.ä. abgefragt werden soll und einmal wenn deine View neue Methoden/Felder benötigt. Mehrere Änderungsgründe wiederum führen zu einer erhöhten Wahrscheinlichkeit von Fehlern.
(mal davon abgesehen, dass jede DAOImplementierung dann deine 'EL-Methoden' zur Verfügung stellen müsste um austauschbar zu sein)

Besorg dir am besten mal das Buch 'Clean Code' von Martin Fowler. Gehört auf den Schreibtisch eines jeden entwicklers 


Im Übrigen gefällt mir die Benennung: Controller hier wesentlich besser, als DAOManager. Letzteres suggeriert doch irgendwie, dass es der Verwaltung unterschiedlicher DAO dient und nicht der Kontrolle/Business-Logik der App. (Der Richtige Ort für deine JSF-Felder/Methoden ist es dann zwar - glaube ich - auch nicht. Aber fürs erste auf jeden Fall besser)


----------



## Andgalf (1. Feb 2012)

DerFeivel hat gesagt.:


> Besorg dir am besten mal das Buch 'Clean Code' von Martin Fowler. Gehört auf den Schreibtisch eines jeden entwicklers



[Klugs*****ermode] Clean Code ist nicht von Fowler, sondern von "uncle Bob" Martin[/Klugs*****ermode]


----------



## maki (1. Feb 2012)

Clean Code ist nicht von Martin Fowler, sondern von Robert "Uncle Bob" Martin und "Clean Code Developer" hat nicht wirklich etwas mit dem Buch "Clean Code" zu tun 

Ansonsten hat eine EJB rein gar nix mit dem C in MVC zu tun, MVC gibt es nur in der View/GUI, früher hat man EJBs auch "ApplicationController" genannt.

Adam Bien hat mal ein Buch über Muster in J2EE geschrieben und welche davon in JEE wegfallen können.
Dazu gehörte u.a. auch das DAO Muster, reine DAOs sind IMO zustandslos... Bien empfiehlt den EM in den (Stateful-) SessionBeans direkt zu verwenden, in Stateful SBs dann eben über den extended PersistenceContext.


----------



## Sym (1. Feb 2012)

SirWayne hat gesagt.:


> Der ExtendendPersistenceContext ist für eine long running session da, damit du in der Session immer wieder den gleichen em bekommst..


Wofür der da ist, ist mir klar. Warum der TE das nutzen sollte nicht. 

@TE:

Nimm Dir eine Stateless EJB. Nutze den EntityManager. Verzichte auf den Begriff DAO. 

Diese EJBs nennst Du Businessschicht und auf die greifst Du mit Deiner View zu.

Wie Maki schon schrieb, hat diese Schicht nichts mit MVC oder anderen UI-Patterns zu tun. Die reine UI Logik machst Du auch im UI und nicht in den EJBs. 

Wenn Du JSF benutzt, hast Du automatisch das MVC-Pattern und natürlich kannst Du dann über EL auf die EJBs zugreifen - daran ist nichts verwerflich, solange dort keine Navigation geschieht.

Und wenn es später um Nachrichten geht und Du EJB ein wenig besser kennst, schaust Du Dir MessageDrivenBeans an.

Viel Spaß.


----------



## DerFeivel (1. Feb 2012)

Mea Culpa, war natürlich Robert Martin. *Asche auf mein Haupt* Blöde Martins....


Wie du darauf kommst, dass ich Clean-Code-Developer mit dem Buch von Robert Martin gleichsetze, ist mir aber nicht ganz klar. Sie handeln von der gleichen Thematik und sind m.E. für jemanden mit seinen Ambitionen ein Must-have.


Warum sollte man in J2EE auf DAOs verzichten? Any Links?


----------



## Gast2 (1. Feb 2012)

Sym hat gesagt.:


> Wenn Du JSF benutzt, hast Du automatisch das MVC-Pattern



Naja JSF gibt dir Hilfestellungen vielleicht, aber automatisch hast du keine MVC Architektur...


----------



## maki (1. Feb 2012)

DerFeivel hat gesagt.:


> Mea Culpa, war natürlich Robert Martin. *Asche auf mein Haupt* Blöde Martins....


Hehe... kann schon mal vorkommen 



DerFeivel hat gesagt.:


> Wie du darauf kommst, dass ich Clean-Code-Developer mit dem Buch von Robert Martin gleichsetze, ist mir aber nicht ganz klar.


Dachte du hättest die CCDI mit CC gleichgesetzt, haben aber nciht wirklich etwas miteinander zu tun 



DerFeivel hat gesagt.:


> Sie handeln von der gleichen Thematik und sind m.E. für jemanden mit seinen Ambitionen ein Must-have.


Nicht wirklich, CCDI verkauft Kurse/Fortbildungen... will die CCDI jetzt nicht schlechtreden, aber "gleiche Thematik" ist es nicht, ähnlich schon.



> Warum sollte man in J2EE auf DAOs verzichten? Any Links?


Nicht in J2EE, sondern in JEE 

Adam Bien schrieb mal ein Buch "Book: Real World Java EE Patterns – Rethinking Best Practices", darin geht es eben um alte J2EE Pattern die in JEE überholt sind, Bien hat u.a. das DAO zu "obsolete" erklärt. Ist imho nicht ganz falsch, aber da kann sich jeder seine eigenen Gedanken zu machen.

JPA/EJB3 killed the DAO : Adam Bien's Weblog

Nebenbei, bei JSF geht es IMHO um MV*P*, MVC ist ja recht wischi-waschi


----------



## Gast2 (1. Feb 2012)

DerFeivel hat gesagt.:


> Warum sollte man in J2EE auf DAOs verzichten? Any Links?



Meistens sind sie unnütz und blähen Code nur auf, seit es den EM gibt.

Bsp.

```
public PersonDAO{

private EntityManager em;

public Preson getPerson(Long id){
 return em.find(Person.class,id);
}
```


```
public PersonService

PersonDAO dao;

public Preson getPerson(Long id){
 return dao.getPerson(id);
}
```

Warum nicht gleich einfach so? Wofür ist das DAO gut?


```
public PersonService

private EntityManager em;

public Preson getPerson(Long id){
 return em.find(Person.class,id);
}
```

Ein DAO mit Interface würde Sinn machen, wenn man mehrere Arten der Persisitierung bereitstellt.
z.B. Speichern im FileSystem, in einer DB etc.
Aber wie oft kommt sowas schon vor? Außerdem könnte man das auch im Service unterscheiden...


----------



## Sym (1. Feb 2012)

SirWayne hat gesagt.:


> Naja JSF gibt dir Hilfestellungen vielleicht, aber automatisch hast du keine MVC Architektur...


Eigentlich schon.

Ist hier z.B. gut beschrieben.


----------



## DerFeivel (1. Feb 2012)

maki hat gesagt.:


> Hehe... kann schon mal vorkommen
> 
> 
> Dachte du hättest die CCI mit CC gleichgesetzt, haben aber nciht wirklich etwas miteinander zu tun
> ...




Gleichgesetzt nicht. Aber es geht in beiden imho um die gleiche Thematik (Sauberer Code). Das CCD da noch eine Gerüst (Wertesystem) drum baut und das Ganze vermarktet, ändert nichts an der Thematik. Diverse Prinzipien aus dem Buch werden in CCD (teils anderes benannt, bzw. dem Kind überhaupt einem Namen gegeben) auch aufgegriffen.


 Danke für den Link (Der Titel erklärt auch deine Haarspalterei). Im Grunde genommen hat er da aber nichts abgeschafft (Der EntitityManager ist imho nichts anderes als eine - standardisierte - Implementierung des Patterns)


----------



## DerFeivel (1. Feb 2012)

SirWayne hat gesagt.:


> Meistens sind sie unnütz und blähen Code nur auf, seit es den EM gibt.
> Ein DAO mit Interface würde Sinn machen, wenn man mehrere Arten der Persisitierung bereitstellt.
> z.B. Speichern im FileSystem, in einer DB etc.
> Aber wie oft kommt sowas schon vor? Außerdem könnte man das auch im Service unterscheiden...



Also während meines täglichen Arbeitsalltag schon mehrmals Oo


----------



## maki (1. Feb 2012)

> Gleichgesetzt nicht. Aber es geht in beiden imho um die gleiche Thematik (Sauberer Code). Das CCD da noch eine Gerüst (Wertesystem) drum baut und das Ganze vermarktet, ändert nichts an der Thematik. Diverse Prinzipien aus dem Buch werden in CCD (teils anderes benannt, bzw. dem Kind überhaupt einem Namen gegeben) auch aufgegriffen.


"Diverse Prinzipien" aufgreifen, umbennen, verändern, drumherum etwas bauen, vermarkten, etc. pp. -> ist IMHO nicht mehr die gleiche Thematik, aber lassen wir das, ich halte von Buch "Clean Code" sehr viel 



> Danke für den Link (Der Titel erklärt auch deine Haarspalterei). Im Grunde genommen hat er da aber nichts abgeschafft (Der EntitityManager ist imho nichts anderes als eine - standardisierte - Implementierung des Patterns)


Solltest dir vielleicht mal den einen oder anderen Blog von Bien durchlesen, oder gar das Buch, da würde dir schon auffallen was unterschiedlich ist 

"nichts abgeschafft" ist leider falsch, aber dazu müsste man wissen was vorher so die Standard Patterns für J2EE waren, ValueListHandler zB., ergibt gar keinen Sinn mit POJOs/EJB3, usw.

Dass der EM (laut Bien) das DAO in den meisten Fällen abgeschafft hat ist wohl klar, auch ist der EM nicht einfach nur ein DAO, ähnlich ja, aber nicht dasselbe 

Es kann zB. Sinn machen trotz des EMs noch DAOs zu verwenden, hat was mit vermeiden von redundanzen oder Spezialisirungen zu tun, ist bei ganz simplen CRUD Beispielen eher selten der Fall, die meisten "alten" DAOs sind nur in 2 Fällen spezialisiert, einmal den Rückgabetypen (lässt sich durch generics erschlagen), dann um spezielle Query zu beinhalten, letzteres kann immer noch ein Grund für DAOs sein.


----------



## Gast2 (1. Feb 2012)

Sym hat gesagt.:


> Eigentlich schon.
> 
> Ist hier z.B. gut beschrieben.


Ja trotzdem kannst du in deinem Model immer noch nicht MVC konforme Sachen machen, davor bewahrt dich keiner... 
Du kannst Model und EJB mischen usw.

Ich weiß auch nicht ob ich so toll finde, dass ein Model auf ein EJB zugreifen soll, ist für mich eher Aufgabe für den Controller. Deshalb habe ich schau schon gesehen dass ein Controller ein ManagedBean ist und das Model einfaches POJO...

Also JSF hat nichts zwangsläufig mit MVC(P) zu tun du kannst genau so Fehler in der Architektur machen, wie bei jeder anderen Anwendung auch.

EDIT: 
6.*JSF application with a controller

EDIT EDIT schau mal hier unter 2.5
JSFAtWork, JSF 2.0 und Apache MyFaces
So sind deine ManagedBeans deine Vermittler bzw. Presenter bzw. Controller.

Aber genauso kannst du sie als Model "mißbrauchen" von dem her hast du kein automatisches MVC


----------



## Gast2 (1. Feb 2012)

maki hat gesagt.:


> "
> Es kann zB. Sinn machen trotz des EMs noch DAOs zu verwenden, hat was mit vermeiden von redundanzen oder Spezialisirungen zu tun, ist bei ganz simplen CRUD Beispielen eher selten der Fall, die meisten "alten" DAOs sind nur in 2 Fällen spezialisiert, einmal den Rückgabetypen (lässt sich durch generics erschlagen), dann um spezielle Query zu beinhalten, letzteres kann immer noch ein Grund für DAOs sein.



FULL ACK...

Zusätzlich finde ich auch, dass DAO's bei einfachen Suchfunktionen vermieden werden können.


----------



## Sym (2. Feb 2012)

@SirWayne:

Du hast natürlich recht, es gibt verschiedene Meinungen zum Thema MVC und Abbildung in JSF. Dennoch wird das Framework als MVC-Framework gehandelt - das ist jedenfalls meine Erfahrung.

Das man ein Pattern aber auch missbrauchen kann, bestreite ich nicht.


----------



## Gast2 (2. Feb 2012)

Sym hat gesagt.:


> Dennoch wird das Framework als MVC-Framework gehandelt - das ist jedenfalls meine Erfahrung.



Das wird gern so hingestellt, ist es aber nicht. Wie du aus oben genannten Gründen siehst...


----------



## Sym (2. Feb 2012)

SirWayne hat gesagt.:


> Das wird gern so hingestellt, ist es aber nicht. Wie du aus oben genannten Gründen siehst...


Ich sehe, dass man es anders nutzen kann. Dass es per se kein MVC Framework ist, sehe ich nicht so.


----------



## Gast2 (2. Feb 2012)

Sym hat gesagt.:


> Ich sehe, dass man es anders nutzen kann. Dass es per se kein MVC Framework ist, sehe ich nicht so.



Gut wenn du dass so siehst, dann sind Swing , Eclipse RCP (MVA), Struts, Wicket, Tapestry,Web Dynpro etc. auch alles MVC Frameworks... =)
Aber es bringt dir keinen Vorteil oder?


----------



## membersound (4. Feb 2012)

Danke euch allen, das hilft mir schon viel weiter!

Ein Problem, was ich gerade habe (mal einfach unabhängig davon, ob man nun DAOs nutzt oder nicht):

Angenommen: ich habe eine JSF Seite um einen Customer zu erstellen (mit InputField für Name, sowie ein Register Button).

Wenn ich meinen Service stateful mache, dann weiß ich in etwa wie es geht.
Mir stellt sich allerdings die Frage: ist es nicht richtiger @Stateless zu nutzen? Denn es handelt sich ja um eine in sich abgeschlossene Aktion. Die 1x aufgerufen wird (mit dem Click auf Register), dann 1x durchläuft und damit fertig ist.

Was müsste ich an meinem Code ändern, falls ich @Stateless nehme? Vor allem: wie bekomme ich die InputFields von der JSF Page gespeichert im stateless Fall? Denn ein stateless Service hat ja kein customer-Field was ich persisten könnte...


```
@Stateful
@RequestScoped
@Named
public class CustomerService() {
	@Inject
	CustomerDao customerDAO;

	private Customer newCustomer = new Customer();

	public void save() {
		customerDao.persist(newCustomer);
	}

	@Produces
	public Customer getNewCustomer() {
		return newCustomer;
	}
}
```

Meine JSF dann ungefähr so:

```
<h:inputText id="name"value="#{newCustomer.name}" />
<h:commandButton id="register" action="#{customerService.save()}" value="Register" />
```

Danke vielmals!


----------



## Sym (4. Feb 2012)

Wieso solltest Du dort keinen Customer haben? Wenn Du einen ViewScope verwendest, dann sollte alles klappen.


----------

