-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Umgang mit der Session
PostPosted: Tue Oct 07, 2008 6:17 pm 
Newbie

Joined: Fri Feb 08, 2008 7:03 am
Posts: 5
Hallo liebe Hibernate-Community,

ich komme noch nicht wirklich mit dem Umgang mit der Session klar:
Ich benutze das Session-per-request-Pattern, welches in meinem Code dann beispielsweise so aussieht:

Code:
       
public static Album getAlbum(int id)
{
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Album result = (Album) session.load(Album.class, id);
        session.getTransaction().commit();
        return result;
}


Es wird also eine Session erzeugt, das Album-Objekt aus der Datenbank geladen und danach mit "commit" die Session ins Nirvana geschickt. Soweit klar.

Ich habe hauptsächlich die Klassen Bild und Album. Zwischen Album und Bild besteht eine Assoziation. Nun möchte ich ein Album-Objekt mit obiger Methode aus der Datenbank laden und danach folgendermaßen die Assoziation benutzen:

Code:
int bilderInAlbum = meinAlbum.getBilder().size()

(getBilder liefert eine ArrayList zurück, mit der die Assoziation realisiert wird.)

Dabei bekomme ich jedoch leider folgende Exception:
Code:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session


Hibernate kann die Bilder aus der ArrayList nicht nachladen, da die Session ja geschlossen ist. Also habe ich zunächst versucht, LazyLoading auf folgende Weise zu deaktivieren, indem ich die Assoziation zu den Bildern auf Fetch=Eager gestellt habe:

Code:
@OneToMany(mappedBy = "album",fetch=FetchType.EAGER)
    List<Bild> bilder = new ArrayList<Bild>();


Dies hat jedoch keine Abhilfe geschaffen. Und genau hier hänge ich, da durch das deaktivierte Lazy-Loading Hibernate die Bild-Objekte ja direkt beim Auslesen der Album-Objekte mitnehmen müsste. Dies tut er aber offensichtlich nicht. Kann mir jemand erklären warum, und wie ich das Problem löse?

Ich habe eine Möglichkeit gefunden, dass Problem zu umgehen, indem ich bei einem reinem laden eines Objektes die Session einfach nicht mehr committe. Dadurch entsteht jedoch das Problem, dass Hibernate auf einmal verschiedene Sitzungen hat, sodass wenn man Objektattribute ändert, in die Datenbank schreibt, und dann per Hibernate darauf zugreift, die Objektattribute zufällig die alten oder die neuen Werte haben können. Dies ist also auch keine Lösung.

Ich bitte um Aufklärung.

Vielen Dank schon einmal. Bin leider noch ein Hibernate-Anfänger.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 09, 2008 1:15 pm 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
Also ich habe solche Konstruktionen öfters und mappe (zwar meist als Set, aber das ist egal!) solche Collections ebenfalls mit
Code:
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)


wobei die cascade-Option beim Laden ja nix zu sagen hat (macht mir nur automatischen save, wenn die Collection sich ändert).

Also, ich vermute eher, du hast anderswo ein Problem. Wie sieht denn das reverse-Mapping aus (auf der Bild-Seite)? Da solche Beziehungen bidirektional sind, sollten bei Seiten richtig versorgt sein.

_________________
Carlo
-----------------------------------------------------------
please don't forget to rate if this post helped you


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 12, 2008 7:18 pm 
Newbie

Joined: Fri Feb 08, 2008 7:03 am
Posts: 5
Auf der anderen Seite sieht es so aus:

Code:
@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
    private Album album = null;

Ich verstehe den Fehler nicht wirklich. Außerdem habe ich noch eine dritte Klasse "Tag", zu der auch eine Assoziation von Bild aus besteht, bei der ich den fetchType allerdings nicht auf EAGER gestellt habe, da davon einige tausend Objekte vorhanden sind und die Anwendung zu langsam werden würde. Wobei an der Stelle, an der der Fehler auftritt ja garnicht auf die Tags zugegriffen wird, weshalb dies nicht die Fehlerquelle sein sollte, oder?

Ein Bild hat außerdem noch eine Hashtabelle, die allerdings transient ist, und somit den Fehler nicht verursachen dürfte:
Code:
private transient Hashtable fehlertabelle = new Hashtable();


Gibt es noch eine andere Möglichkeit, das Problem zu umgehen? Wie würde man das z.B. machen, wenn man LazyLoading an dieser Stelle bewusst benötigen würde, wenn es z.B. zu viele Objekte gibt, sodass es ineffizient wäre, alle Objekte direkt zu laden?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 14, 2008 4:26 am 
Beginner
Beginner

Joined: Fri Sep 26, 2008 2:39 am
Posts: 20
Bin selber noch Anfänger, aber meinem Verständnis nach sieht es so aus:

Um Lazyloading nutzen zu können darf die Session eben noch nicht geschlossen sein (da ja die Objekte sonst detached sind).

Ließe sich deine Anwendung so umstellen, dass du die Session öffnest, die Objekte holst, deine Aktionen auf den Objekten ausführst und dann erst die Session schliesst?

So würden dann ja auch Änderungen an den Objekten direkt ohne weiteren Code in die Datenbank übernommen.

viele grüße, jp


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 16, 2008 10:52 pm 
Newbie

Joined: Thu Oct 16, 2008 10:48 pm
Posts: 1
Hallo!

Nur eine dumpfe Ahnung, aber versuch's mal mit get statt load

Das hatte ich mir mal als Notiz aufgeschrieben:

Quote:
Ein mit load() zugewiesenes objekt ist im Gegensatz zu get() auch nicht ausserhalb der transaction erreichbar (also nachdem commit() ausgeführt wurde).


Bin Auch Anfaenger ;-)

Wenn das nicht klappt, koenntest du es mal mit 'programmatischer' Konfiguration probieren (anstelle von Annotationen):

Code:
Album result = (Album) HibernateUtil.getSessionFactory().getCurrentSession().setFetchMode("bilder", FetchMode.EAGER).get(Album.class, id);



Frank


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.