Hibernate - Collection in 2 Sessions
lima-city → Forum → Programmiersprachen → Java
angabe
ankommen
annotation
arbeitskollege
beliebig gleichzeitig laufen
bestehen
code
gefundenen texte
implementierung
kopie
laufen
markieren
objekt
problem
queue
regel
session
struktur
treten
url
-
Hallo zusammen,
ich habe da ein kleines Problem mit Hibernate, was mich seit Wochen beschäftigt. Leider konnte ich bislang keine Lösung finden, weshalb ich auch davon ausgehe, dass das auf dem Weg auch nicht ohne weiteres geht. Als letzte Option daher hier meine Frage:
Ich arbeite an einer WebApp mit Hibernate. Dabei öffne ich für jeden Request, wo es nötig ist, eine neue Hibernate Session. Das ganze sieht dann etwa so aus:
Session session = ((SessionFactory) request.getServletContext().getAttribute("SessionFactory")).openSession(); user.setCompilationActiveById(id); session.saveOrUpdate(user); session.flush(); session.close();
Jetzt habe ich das Problem, dass ab und an gleichzeitig Requests auf dem gleichen Objekt ankommen. Dabei bekomme ich dann folgende Exception, zu der ich bereits einige Geschichten gelesen habe:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
Leider konnte ich die gefundenen Texte nicht so recht mit meinem Problem in Verbindung bringen, da bei den zahllosen Hilfegesuchen immer die Session nicht geschlossen wird. Dies ist bei mir definitiv der Fall. Ich gehe daher von einem Concurrency-Problem aus.
In der Regel sind 95% der Requests ausschließlich lesend. Daher war meine Idee, dass lesende Datenbankoperationen eigentlich beliebig gleichzeitig laufen können müssten. Immerhin können sie sich nicht gegenseitig behindern. Es wäre auch nicht schlimm, wenn ich nicht immer die aktuellsten Daten lese (, sodass 1 Schreiboperation und beliebig viele Leseoperationen laufen könnten).
Gibt es bei Hibernate eine Möglichkeit Sessions irgendwie zu markieren, dass Objekte gleichzeitig in verschiedenen Sessions instantiiert werden können? Wie lösen andere Seiten dieses Problem? Eventuell kommt bei mir erschwerend hinzu, dass im Hintergrund auch noch Threads laufen, die in regelmäßigen Abständen auf den Objekten arbeiten. Dadurch tritt der Fehler bereits bei einem Nutzer relativ häufig auf.
Leider konnte ich andere Lösungsansätze der gleichen Fehlermeldung nicht wirklich auf mein Problem übertragen. Wenn mir also jemand in irgend einer Form weiterhelfen könnte, wäre ich sehr erfreut.
Viele Grüße,
loadi
P.S.: Sollten mehr Angaben benötigt werden, fragt einfach gezielt nach. Der Post kam mir nur bereits recht lang vor, weshalb ich ihn etwas gekürzt habe. -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Ich glaube, du suchst vielleicht nach SessionFactory.getCurrentSession(), sprich: Nicht bei jedem Request eine neue Session aufmachen, sondern ein und dieselbe Session für mehrere Requests nutzen. Löst jetzt weniger das Problem, dass Objekte in mehreren Sessions sein können, sondern reduziert eher die Anzahl der Sessions.
Beitrag zuletzt geändert: 7.4.2015 19:20:06 von tavern -
Hi tavern,
danke für deine Antwort. Theoretisch ist das eine Option. Aber an nahezu jeder Stelle wird einem geraten lieber openSession() zu nehmen und für jeden Request eine eigene Session zu öffnen. Daher war ich dem immer eher abgeneigt.
Ein Arbeitskollege hatte noch 2 weitere Ansätze. Ich könnte das Problem auch vermeiden, indem ich in meiner Objektstruktur auf ein Cascade.ALL bei den enthaltenen Objektlisten verzichte. Dies war mir jedoch speichertechnisch nicht so wirklich möglich.
Meine Lösung bestand aus einem zusätzlichen Value-Objekt für jedes Hibernate-Objekt. Ich arbeite ausschließlich auf dem Valueobjekt, was von der Struktur her eine Kopie des Hibernate-Objekts ist (nur ohne Annotationen). Ich habe mir dazu noch ein eigenes Cachingsystem geschrieben. So werden die Valueobjekte gecached. Beim Persistieren wird ein Valueobjekt in ein Hibernateobjekt konvertiert und gespeichert. Das Speichern übernimmt in meiner Implementierung ein separater Thread (der eine Queue abarbeitet). Dadurch vermeide ich Überschneidungen. Ein netter Nebeneffekt sind deutlich kürzere Seitenladezeiten.
Die Implementierung war zwar ziemlich aufwändig, aber ich bin mit der Lösung sehr zufrieden.
Viele Grüße,
loadi -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage