Ich bekomme diese Ausnahme in einem Controller einer Webanwendung basierend auf Feder-Framework mit Hibernate. Ich habe viele Wege versucht, dem entgegenzuwirken, konnte es aber nicht lösen.StaleObjectStateException Zeile wurde aktualisiert oder gelöscht von
In der Controller-Methode, handleRequestInternal
, gibt es Aufrufe an die Datenbank hauptsächlich für 'lesen', es sei denn, es ist eine Übermittlungsaktion. Ich habe Spring Session verwendet, aber umgezogen zu getHibernateTemplate()
und das Problem bleibt immer noch.
im Grunde, löst dieser zweite Aufruf der Datenbank diese Ausnahme aus. Das heißt:
1) getEquipmentsByNumber(number)
{Zuerst wird ein Gerät aus der Datenbank abgerufen, basierend auf der 'Nummer', die eine Liste von Eigenschaften enthält und jede Eigenschaft eine Werteliste enthält. I Schleife durch diese Werte (primitive Objekte Strings) auf Variablen lesen in)
2) getMaterialById(id)
{holt Materialien auf Basis von id}
verstehe ich, dass der zweite Anruf, höchstwahrscheinlich, macht die Sitzung "flush", aber ich lese nur Objekte, und warum löst dann der zweite Aufruf die veraltete Objektstatusausnahme in der Equipment-Eigenschaft aus, wenn nichts geändert wird?
Ich kann den Cache nach dem Aufruf nicht löschen, da er LazyExceptions für Objekte verursacht, die ich an die Ansicht übergebe.
Ich habe gelesen: https://forums.hibernate.org/viewtopic.php?f=1&t=996355&start=0 aber konnte das Problem auf der Grundlage der vorgeschlagenen Vorschläge nicht lösen.
Wie kann ich dieses Problem lösen? Irgendwelche Ideen und Gedanken werden geschätzt.
UPDATE: Was ich nur getestet, dass in der Funktion getEquipmentsByNumber()
nach den Variablen aus der Liste der Eigenschaften zu lesen, ich dies tun: getHibernateTemplate().flush();
und jetzt die Ausnahme ist auf dieser Linie eher dann der Anruf Material zu holen (das ist getMaterialById(id)
).
UPDATE: Vor dem expliziten Aufruf von Flush entferne ich das Objekt aus dem Sitzungscache, sodass kein veraltetes Objekt im Cache verbleibt.
getHibernateTemplate().evict(equipment);
getHibernateTemplate().flush();
OK, so jetzt ist das Problem zum nächsten Abruf von DB nach diesem Schritt verschoben. Ich nehme an, ich muss die Methoden als synchronisiert markieren und die Objekte entfernen, sobald ich ihre Inhalte gelesen habe! es klingt nicht sehr gut.
UPDATE: Die handleRequestInternal
Methode "synchronisiert". Der Fehler ist verschwunden. Natürlich nicht die beste Lösung, aber was zu tun ist! Versucht in handleRequestInternal
, um die aktuelle Sitzung zu schließen und eine neue zu öffnen. Es würde jedoch dazu führen, dass andere Teile der App nicht ordnungsgemäß funktionieren. Versucht, ThreadLocal
zu verwenden, das auch nicht funktionierte.
Wenn Sie den Code für die Methode posten könnten, die die Ausnahme wirft, werde ich es weiter betrachten. Klingt irgendwie fischig – walnutmon