2009-07-16 6 views
2

Ich bin in eine Situation geraten, in der das Hibernate-Objekt, das von der Abfrage zurückgegeben wurde, unzuverlässig ist.Unzuverlässige Hibernate-Objekte

Betrachten Sie den folgenden Code ein:

MyClass myClass = myDAO.get(id); 

myClass.getId(); //This works 
myClass.getName(); //This returns null sometimes, and works sometimes 

Hier ist meine get Methode:

@SuppressWarnings("unchecked") 
public T get(ID id) 
{ 
    Session s = getSession(); 
    T entity = (T) s.load(getPersistentClass(), id); 
    s.disconnect(); 
    return entity; 
} 

Jetzt verstehe ich, dass dieses Objekt ein Proxy ist, und wird faul geladen sein, aber ich würde erwarten, dass es entweder immer arbeiten oder nie arbeiten. Mache ich hier etwas falsch?

Antwort

3

Dies kann oder kann nicht die Ursache sein, aber Sie sollten wahrscheinlich nicht Session.load() verwenden, sollten Sie Session.get() verwenden.

load() gibt die persistente Instanz als aktuell von Hibernate geladen zurück, und es ist möglich, dass diese teilweise gefüllt ist, je nachdem, was vorher passiert ist.

get() ist robuster. Versuch das.

+0

load() wird aus Leistungsgründen verwendet (gemäß Empfehlung des Hibernate-Teams). Ich gebe get() einen Schuss, aber ich würde immer noch erwarten, Hibernate das Mitglied zu holen, wenn Sie danach gefragt ... – Jesse

+1

Ich hatte ähnliche, wenn nicht das gleiche Problem mit Last, änderte ich um zu bekommen() und alles ist wieder gut () – jottos

+0

Ich markiere dies als beantwortet. Ich habe vor einiger Zeit von load() zu get() gewechselt und seitdem kein Problem mehr. – Jesse

1

Problem ist "laden" lädt einen Proxy des Objekts und nicht tatsächlich die Datenbank. Wenn das Objekt jedoch bereits geladen (und gefüllt) wurde, d. H. Im Cache der Ebene 1, wird es diese Instanz bereitstellen.

Wenn Sie load verwenden, wird es nur dann tatsächlich auf die Datenbank treffen, wenn es absolut notwendig ist, d. H. Wenn Sie nach einem der Felder des Objekts fragen.

Get auf der anderen Seite wird tatsächlich die Datenbank treffen.

Für Ihre Zwecke würde ich empfehlen, dass, ob Sie laden oder holen Sie stellen Sie sicher, dass das Objekt ausgefüllt ist, bevor es zurückgibt. Bevor Sie es zurückgeben, rufen Sie einen der Getter darauf. Dann können Sie garantieren, dass es ausgefüllt ist.

Eine nützliche Übung wäre es, sql-Protokollierung (org.hibernate.SQL = DEBUG) zu aktivieren, durch sie zu debuggen und zu sehen, welche SQL-Anweisungen ausgeführt werden.

Sie könnten auch in Betracht ziehen, das persistente Objekt so zu konfigurieren, dass es nicht faul ist. Auf diese Weise erhalten Sie jedes Mal, wenn Sie load oder get verwenden, ein vollständig gefülltes Objekt.

+0

Ich würde vermeiden, eifrig holen im Hibernate Mapping, wie Sie vorgeschlagen. Das Eager-Laden standardmäßig kann zu großen Leistungseinbußen beim Laden von Auflistungen der zugeordneten Klasse oder beim Abfragen von Ansichten führen, bei denen nicht alle Felder der zugeordneten Klasse angezeigt werden müssen. Aus diesem Grund ist das verzögerte Laden in Hibernate 3.x der Standard –

Verwandte Themen