2009-05-22 8 views
3

Ich habe einen Prozess, der eine Struktur in der Datenbank aktualisiert und führt dabei Lesevorgänge für doppelte Entitäten durch.Hibernate ruft Flush auf Find- Ursachen Not-Null Fehler

Ich finde, dass eine criteria.uniqueResult zu tun versuchen() in der Mitte durch diesen Prozess verursacht den folgenden Fehler:

org.hibernate.PropertyValueException: not-null property references a null or transient value

Graben durch den Stack-Trace, ich sehe, dass die uniqueResult() wird die Spülung Sitzung versucht, Aktualisierungen durchzuführen, die noch nicht bereit sind, in die Datenbank zu gehen.

at org.hibernate.engine.Cascade.cascade(Cascade.java:153) 
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154) 
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145) 
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88) 
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:58) 
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:996) 
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1589) 
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306) 
at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:328) 
at com.inversion.dal.BaseDAO.findUniqueByCriterion(BaseDAO.java:59) 

Habe ich hier etwas falsch gemacht?

Jede Hilfe sehr geschätzt.

Marty

Antwort

3

Ruhezustand merkt sich mit Objekten muss gespeichert werden. Wenn Sie eine Auswahl treffen, werden diese Änderungen durch den Ruhezustand gelöscht. Dies stellt sicher, dass die Auswahl die richtigen Ergebnisse liefert.

Wenn Sie flushmode auf einen anderen Wert als FlushMode.AUTO setzen, wird dieses Verhalten verhindert. Aber der Fehler ist in Ihrem Code, wo Sie ein unvollständiges Objekt in den Ruhezustand übergeben, um persistent zu bleiben oder zu aktualisieren. Die richtige Lösung besteht also darin, das Objekt später in den Ruhezustand zu überführen, wenn es abgeschlossen ist.

+0

Während das Übergeben eines unvollständigen Objekts in den Ruhezustand ein guter Kandidat für die Null-Constraint-Verletzung ist, gibt es viele Codepfade, die einen solchen Fehler auslösen könnten und Änderungen an bereits in der Sitzung vorhandenen Elementen betreffen Der Fehler tritt auf. – Jherico

2

Auto-Spülung auf dem Session-Objekt Schalten Sie diese Ausnahme zu beheben.

Session s; 
// if you're doing transactional work 
s.setFlushMode(FlushMode.COMMIT); 
// if you want to control flushes directly 
s.setFlushMode(FlushMode.MANUAL); 

Dies ist jedoch nicht Ihr Fehler. Etwas früheres in Ihrem Code verursacht, dass sich die Objekte im Speicher in einem ungültigen Zustand befinden, der versucht wird, während des Autoflushs in der Datenbank gespeichert zu werden.

+0

Ich verwende Anmerkungen, um Transaktionsgrenzen zu markieren - @Transactional (readOnly = false). Ich dachte, dass dies der bevorzugte Weg ist, Grenzen zu handhaben, anstatt manuell in meinem Code? Außerdem befindet sich die Entität in einem ungültigen Zustand, aber ich bin noch nicht bereit, es zu übernehmen - Hibernate macht das während eines SELECT-Vorgangs selbstständig. Warum? –

+1

Nur weil Sie in einer Transaktion sind, bedeutet das nicht, dass SQL nicht gegen die Datenbank ausgeführt wird. FlushMode steuert, wenn die SQL ausgeführt wird, nicht wenn die Transaktion festgeschrieben wird. Wenn Sie Objekte erstellen möchten, deren Status für die Datenbank ungültig ist, müssen Sie die Spülung eventuell auf einen späteren Zeitpunkt verschieben, wie es Jherico vorschlägt. –

0

Ich habe mir viele Male die Haare rausgezogen, um diesen Problemen auf den Grund zu gehen. Das Problem ist, dass es so schwierig ist, an die Ursache des Problems zu kommen.

Wenn Sie Ihren Verstand sind kurz vor dem Ende auch die unterstützenden Anfragen wie findAll in einer neuen Sitzung ausführen:

Domain.withNewSession { session -> ... } 

Das hat in der Regel umgangen, das Problem für mich in den meisten Fällen.

Verwandte Themen