Hibernate Session: Wie in alle Klassen

Status
Nicht offen für weitere Antworten.

smung

Mitglied
Hi, ich habe mal eine Frage wie ihr das handhabt.
Ich baue mir in meiner Start Klasse eine Hibernate session auf. Wie realiesiert ihr das, das alle auf diese session zugreifen können. Also alle Methoden und Klassen?. Reicht ihr die Session weiter beim instanziieren der Klassen? Reicht ihr die Main weiter und lasst die session public?

Wie macht ihr das?

gruß

smung
 
Ja, Spring ist ein Framework das du einfach per jar in dein Projekt einbinden kannst.
Spring nimmt dir u.a. genau diese Aufgabe ab, indem du nur noch deklarativ per Annotations "erklärst", das ein bestimmtes Objekt von einer Klasse benötig wird. Spring stellt es dir dann automatisch zur Verfügung.
 
Die Hibernate Session sollte kurzlebig sein. Du solltest sie also öffnen, wenn Du sie brauchst und schließen, wenn sie nicht mehr gebraucht wird. Stattdessen machst Du die SessionFactory Deinen Objekten zugänglich. Darüber können sie sich bei Bedarf eine Session holen.

Solltest Du doch mit nur einer oder wenigen Sessions arbeiten wollen, dann solltest Du auf den Sesssion Cache achten. Diese wird irgendwann voll laufen, wenn die Session immer offen bleibt.

Wenn Du Spring verwendest, brauchst Du Dich um die Sessions gar nicht mehr zu kümmern. Stattdessen verwendest Du das HibernateTemplate. Das bietet viele nützliche Hilfsmethoden und übernimmt das Session-Management für Dich.
 
hat jemand schon eine desktop anwendung realisiert?

wie macht ihr das? ich kann ja nicht einfach hergehen und sagen O von Klasse A braucht O von Klasse B. Dann instazier ich mir ein A.. in so einem Fall hat dies ja kein B gesetzt. Ausser ich hohl mir A vom ApplicationContext oder A wird sowieso von Spring instaziert.... Haltet ihr euch den ApplicationContext irgendwo in einer static Variable?

Ich hab da eine kleine Beispielapplikation von IBM, in der eigntlich alle Kern Objekte von Spring gesetzt werden, das halt ich aber für einwenig übertrieben. Ich möchte bei einer 10k Klassen Applikation diese xml Datei nicht warten müssen. Ich möchte mir nur in meine Modelklassen meine DAOs inizieren.. dazu brauch ich aber irgendow zentral die Referenz auf den ApplikationContext oder?
 
hat jemand schon eine desktop anwendung realisiert?

wie macht ihr das? ich kann ja nicht einfach hergehen und sagen O von Klasse A braucht O von Klasse B. Dann instazier ich mir ein A.. in so einem Fall hat dies ja kein B gesetzt. Ausser ich hohl mir A vom ApplicationContext oder A wird sowieso von Spring instaziert.... Haltet ihr euch den ApplicationContext irgendwo in einer static Variable?

Ich hab da eine kleine Beispielapplikation von IBM, in der eigntlich alle Kern Objekte von Spring gesetzt werden, das halt ich aber für einwenig übertrieben. Ich möchte bei einer 10k Klassen Applikation diese xml Datei nicht warten müssen. Ich möchte mir nur in meine Modelklassen meine DAOs inizieren.. dazu brauch ich aber irgendow zentral die Referenz auf den ApplikationContext oder?
 
A, B, O, ... ist mir jetzt zu wirr. Drück Dich mal klarer aus. 😉

Normalerweise brauchst Du nirgends den ApplicationContext verteilen, Du kannst doch direkt die Beans injizieren. Falls es doch nicht anders geht, dann implementierst Du das Interface ApplicationContextAware, um den ApplicationContext in Deiner Klasse bekannt zu machen.

Ich möchte mir nur in meine Modelklassen meine DAOs inizieren..
Das ist keine gute Idee. Erstens haben DAOs nix im Business Model zu suchen und zweitens werden die Model-Objekte idR vom OR-Mapper (z.B. Hibernate) generiert. Da müsstest Du schon mit Bytecode-Instrumentation (in Spring Load-Time Weaving genannt) arbeiten, um in solche Objekte (die nicht von Spring erzeugt werden) etwas zu injizieren.
 
Das ist keine gute Idee. Erstens haben DAOs nix im Business Model zu suchen und zweitens werden die Model-Objekte idR vom OR-Mapper (z.B. Hibernate) generiert.

hab mich da falsch ausgedrückt.... also in die Richtung MVC, mein Model bekommt vom Controller die anweisung daten zu laden, Model benutzt DAO um Datenobjekten über Hibernate zu laden, Datenobjekte werden in Model gehalten, Model informiert GUI über änderung, GUI stellt Daten aus dem Model dar. ->>Mit Model hab ich jetzt nicht meine Fachobjekte gemeint.

ApplicationContextAware.. muss ich mir ansehen.

A, B, O... mhn... ok nochmal: mein Service möchte von Spring ein DAO gesetzt bekommen. wenn ich meinen Service mit new instanziere ist das DAO natürlich nicht gesetzt. Wenn aber Spring meinen Service instaziert (über ApplicationContext#getBean("service1") oder weil es schon von einer anderen bean referenziert wurde) dann ist das DAO schon gesetzt... Habe ich jetzt mehrere Services die ich mit new instazieren will, benötige ich meiner meiner Meinung nach eine zentrale Referenz auf den ApplicationContext.... kann aber auch nonsens sein, beschäftige mich noch nicht so lange mit dem thema....

wenn ich ApplicationContextAware implementiere, wird mir dann der Context auch gesetzt wenn ich das Objekt mit new instaziere?
 
Ich mache das bei mir derzeit so, dass ich auf dem Swing Client genau ein Singleton-Objekt (ClientContext) definiert habe, das Zugriff auf alle global verfügbaren Objekte bietet. Dieser ClientContext (hat jetzt nix mit Spring zu tun) wird beim Laden des Clients initialisiert und lädt unter anderem den Spring ApplicationContext. Man kann also über diesen ClientContext an die Spring Beans dran kommen.
Bei mir bekomme ich darüber Zugriff auf meine Remote Services (in meinem Fall ist es eine 3-Schicht-Architektur). Du könntest auf diese Weise Deine DAOs verfügbar machen. Auf diese Weise kannst Du Deinen Client auf herkömmlichen Wege konzipieren. Der Einsatz von Spring und DI beschränkt sich dann dabei lediglich auf die Persistenz (DAOs, Transaktionen).

ApplicationContextAware ist natürlich nur für durch Spring erzeugte Beans zu gebrauchen, insofern bringt Dir das hier nichts.
 
Ich mache das bei mir derzeit so, dass ich auf dem Swing Client genau ein Singleton-Objekt (ClientContext) definiert habe, das Zugriff auf alle global verfügbaren Objekte bietet. Dieser ClientContext (hat jetzt nix mit Spring zu tun) wird beim Laden des Clients initialisiert und lädt unter anderem den Spring ApplicationContext. Man kann also über diesen ClientContext an die Spring Beans dran kommen.

ok verstehe, so ähnlich habs ichs jetzt auch gemacht. wollt nur fragen ob das ok ist.

Zugriff auf meine Remote Services
in welcher form sind diese Services implementiert, wenn ich fragen darf?
 
Die Serveranwendung ist mittels Spring WebApplicationContext auf einem Tomcat deployed. Die Services werden mittels HttpInvoker dem Client bereit gestellt.
 
ARadauer hat gesagt.:
Das ist keine gute Idee. Erstens haben DAOs nix im Business Model zu suchen und zweitens werden die Model-Objekte idR vom OR-Mapper (z.B. Hibernate) generiert.

hab mich da falsch ausgedrückt.... also in die Richtung MVC, mein Model bekommt vom Controller die anweisung daten zu laden, Model benutzt DAO um Datenobjekten über Hibernate zu laden, Datenobjekte werden in Model gehalten, Model informiert GUI über änderung, GUI stellt Daten aus dem Model dar. ->>Mit Model hab ich jetzt nicht meine Fachobjekte gemeint.

ApplicationContextAware.. muss ich mir ansehen.

A, B, O... mhn... ok nochmal: mein Service möchte von Spring ein DAO gesetzt bekommen. wenn ich meinen Service mit new instanziere ist das DAO natürlich nicht gesetzt. Wenn aber Spring meinen Service instaziert (über ApplicationContext#getBean("service1") oder weil es schon von einer anderen bean referenziert wurde) dann ist das DAO schon gesetzt... Habe ich jetzt mehrere Services die ich mit new instazieren will, benötige ich meiner meiner Meinung nach eine zentrale Referenz auf den ApplicationContext.... kann aber auch nonsens sein, beschäftige mich noch nicht so lange mit dem thema....

wenn ich ApplicationContextAware implementiere, wird mir dann der Context auch gesetzt wenn ich das Objekt mit new instaziere?

Ich mache das so - (credits an dieser Stelle an einen Artikel im Javamagazin von Christian Dupuis, hab ich mir leider nicht selbst ausgedacht):

Einen Aspect im Spring Context registrieren und ihm das DAO injecten.
Als Pointcut den Constuktor des Services (oder in meinem Fall, der sicher auch häufig vor kommt, des Domain Objektes) definieren
In einem after-advice das DAO setzen.

genau das selbe verhalten erreichst du aber auch, wenn du deinen Service mit @Configurable annotierst und das DAO mit @Autowired injecten lässt. Die Nutzuing von @Configurable setzt aber leider voraus, dass beim JVM start ein -javaagent gesetzt wird. Deshalb habe ich persönlich immer einfach einen eigenen Aspekt geschrieben, der das DAO (oder was auch immer) setzt.

LG Björn


_____________


Nochmal was an dne Thread-Ersteller:

Wenn du keine Lust hast dich extra noch mit Spring zu beschäftigen, lass es vorerst einfach. Das kannst du später immernoch machen. Im Falle von Hibernate kannst du deine SessionFactory (lieber nicht eine explizite Session) ruhig als Singleton deklarieren und erstmal damit arbeiten. Mit Dependency Injection durch z.B. Spring ist's dann schönen und irgendwann auch einfacher und schneller gemacht. Aber für's erste spricht - meiner Meinung nach - wenig gegen 'nen Singleton
 
BjörnBu hat gesagt.:
Ich mache das so - (credits an dieser Stelle an einen Artikel im Javamagazin von Christian Dupuis, hab ich mir leider nicht selbst ausgedacht):

Einen Aspect im Spring Context registrieren und ihm das DAO injecten.
Als Pointcut den Constuktor des Services (oder in meinem Fall, der sicher auch häufig vor kommt, des Domain Objektes) definieren
In einem after-advice das DAO setzen.

genau das selbe verhalten erreichst du aber auch, wenn du deinen Service mit @Configurable annotierst und das DAO mit @Autowired injecten lässt. Die Nutzuing von @Configurable setzt aber leider voraus, dass beim JVM start ein -javaagent gesetzt wird. Deshalb habe ich persönlich immer einfach einen eigenen Aspekt geschrieben, der das DAO (oder was auch immer) setzt.

Vielleicht habe ich Aradauer auch falsch verstanden, aber es geht doch darum, dass er seine DAOs in Objekten benutzen möchte, die nicht von Spring instanziert wurden.
Ich verstehe nicht ganz, wie Du das mit AOP erreichen willst, ohne Load-Time Weaving (spring-agent.jar) einzusetzen? Es gibt doch nur zwei Möglichkeiten, AOP zu benutzen: entweder mit Proxies oder mit Bytecode-Instrumentation. Letzteres geht nur mit dem spring-agent.jar und Proxies funktionieren nur für Objekte, die auch von Spring erzeugt werden.

Domain Objekte werden ja idR nicht durch Spring erzeugt sondern vom OR-Mapper (z.B. Hibernate). Wie willst Du da Aspekte dran hängen, ohne Load-Time-Weaving zu benutzen? Wüsste nicht dass das mit Proxies zu bewerkstelligen ist, aber lasse mich gerne eines besseren belehren. 🙂
 
der Joinpoint wird fest zur compile-time geweavt. Sprich nach jedem Konstruktor Aufruf setzt der Aspekt das DAO
Der Aspekt selber kann aber ruhig am Anfang instanziert und von Spring verwaltet werden. Dem injecte ich das DAO. Fest in den Bytecode reinmanipuliert ist nur die Logik des Setzens.

Ohne Spring würde null als DAO gesetzt werden. Mit Spring hat der Aspekt das DAO als Referenz und setzt es wunderbar. Habe ich definitiv schon so in der Praxis - bei von Hibernate instanzierten Domain Objekten - gemacht
 
BjörnBu hat gesagt.:
der Joinpoint wird fest zur compile-time geweavt. Sprich nach jedem Konstruktor Aufruf setzt der Aspekt das DAO
Sorry, habs immernoch nicht verstanden: Wie kriegst Du den Joinpoint in die Hibernate Objekte ohne den Einsatz von spring-agent.jar? JDK-Proxies werden doch nur erzeugt, wenn die Objekte als Spring Beans konfiguriert sind? ???:L Für alles weitere braucht man AspectJ / spring-agent.jar.
 
Achso sorry. Ja, ich habe AspectJ genutzt und die Aspekte als beans mit factory-method="apspectOf" definiert. Trotzdem kommt es ohne load time weaving aus.

Sorry für die Verwirrung ich habe mir irgendwie angewöhnt AspectJ statt Spring AOP zu nutzen.
 
Achso ok. Ich wusste gar nicht, dass man AspectJ auch ohne spring-agent.jar benutzen kann. Werde mir das beizeiten mal genauer anschauen. 🙂
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben