Grails Gorm : Objekt verweist auf eine nicht gespeicherte transiente Instanz
Bekomme ich folgende Exception beim speichern einer Instanz der Reise in Grails:
2011-01-26 22:37:42,801 [http-8090-5]
FEHLER Fehler.GrailsExceptionResolver
- Objekt verweist auf eine nicht gespeicherte transiente Instanz - speichern Sie die
transiente Instanz vor dem Spülen: Ruderer
org.hibernate.TransientObjectException:
Objekt verweist auf eine nicht gespeicherte transiente
Beispiel - speichern Sie die transiente Instanz
vor dem Spülen: Ruderer
Das Konzept ist einfach: Für einen boattrip müssen Sie einige Ruderer, ein coxwain (ist auch ein Ruderer) und ein Boot:
Reise aussieht (verkürzt):
class Trip {
Boat boat;
Rower coxwain;
static belongsTo = [Rower,Boat]
static hasMany = [rowers:Rower]
}
und Ruderer (gekürzt)
class Rower {
String firstname;
String name;
Rower reference;
static hasMany = [trips:Trip];
static mappedBy = [trips:"rowers"]
}
Die Reise ist dann im controller gespeichert, wie:
def save = {
def trip = new Trip(params)
//adding Rowers to Trip
if (params.rower instanceof String) {
def r = Rower.get(params?.rower)
if (r != null) {
trip.addToRowers(r)
}
} else {
params?.rower?.each{
rowerid ->
def r = Rower.get(rowerid)
log.info("rowerid (asList): " + rowerid)
if (r != null) {
trip.addToRowers(r)
}
}
}
//saving the new Trip -> EXCEPTION IN NEXT LINE
if(!trip.hasErrors() && trip.save(flush:true)) {
//...
}
//...
}
Ich denke, ich habe die Beziehungen zwischen den Domänen korrekt.
Der Ruderer wird nicht geändert, während es ist Hinzugefügt, um die Reise. Warum nicht Grails wollen, um Sie zu retten? warum ist es eine transiente Instanz?
Hast du irgendwelche logging-Nachricht?
InformationsquelleAutor Daniel | 2011-01-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Leider ist dies ein Problem mit der Art und Weise GORM behandelt Dinge, oder genauer gesagt die Art und Weise, dass es erwartet, dass Sie sich mit Transienten. Wenn Sie nicht bestehen der enthaltenen Klassen, die zunächst die Datenbank (Ruderer in diesem Fall), erhalten Sie diese Ausnahme jede einzelne Zeit.
Mit GORM speichern Sie diese und fügen Sie in einem bottom-up-Mode oder wenn die grails-geht Spülen, um die Verbindung für die nächste Instanz erhalten Sie die transiente Instanz Ausnahme. Die Instanz ist 'transient', weil Ihr nur eine in-memory-Referenz. Bestehen bleiben die Eltern, GORM Bedürfnissen zu verknüpfen, dass ein Elternteil das Kind in der Datenbank. Ohne das Kind wird beibehalten, es hat keine Möglichkeit, das zu tun, das ist, wo die exception kommt.
Wünschte, es gäbe bessere Nachrichten. Nicht, dass seine schwer, aber es wird nervig mit komplexen Hierarchien.
InformationsquelleAutor Guardius
Das Problem war irgendwie anders.
es ist in hier:
welche Referenzen eine coxwain (von Klasse-Ruderer), die nicht gesetzt (id=-1 zurückgegeben wird). Diese konstruiert eine neue Ruderer statt eines "null" - Wert ein. Und dies ist die "nicht gespeicherte transiente Instanz'.
Wenn ich zunächst prüfen, für die eine gültige Instanz, dann funktioniert es 🙂
Danke für die Hilfe!
InformationsquelleAutor Daniel
Nur eine kurze Anmerkung, für alle, Umgang mit singular oder mehrere Parameter mit dem gleichen Namen, mit der
params.list("parameterName")
Helfer können Sie immer wieder eine Listekönnte ein bisschen groovier
finden Sie es, verstecken sich unter 6.1.12 Einfache Art Konverter
InformationsquelleAutor Jukesie
Zuerst dachte ich, es hatte damit zu tun, Kaskadierung spart und belongsTo, wie beschrieben in Das Grails Referenz Abschnitt 5.2.1.3 und Gorm Fallstricke-Teil 2. Da jedoch die Ruderer sind bereits in der DB-ich denke, es sollte funktionieren. Das domain-Modell ist kompliziert für mich, was Sie tun müssen, ist, vereinfachen Sie es und führen Sie einige tests mit Hilfe von Grails-Konsole (ausführen grails-Konsole in Ihrem Projekt-Verzeichnis). Erstellen Sie zuerst ein basic-viele-zu-viele-zwischen Reise und Ruderer und Holen Sie es zum ausführen der gewünschten code. Fügen Sie dann die anderen Teile, die bit für bit, wie die Ruderer die Referenz auf sich selbst. Ich bin mir nicht sicher, dass die mappedBy-Teil überhaupt notwendig ist.
InformationsquelleAutor Fletch
Ich glaube, Sie haben, um zu speichern Sie die Reise, bevor Sie fügen Sie den rover auf die Reise.
Es auch keinen Sinn machen, zu prüfen, ob die Reise hat Fehler, bevor Sie Sie überprüft haben und/oder speichern Sie es.
Versuchen Sie dies:
InformationsquelleAutor Medrod
In vielen Anwendungsfällen, Sie sollten in der Lage sein, um dieses durch die Anwendung der
cascade
Einstellung zu Ihrer Sammlung:https://docs.grails.org/latest/ref/Database%20Mapping/cascade.html
InformationsquelleAutor RMorrisey
Angenommen, Sie verwenden Reise ist hasMany Beziehung mit Ruderer
Eigentlich, schaut es für die neue session. So müssen wir uns halt/rollback der aktuellen Transaktion dann dieser Fehler nicht zu erhöhen, Für,
Versuchen Sie Dieses,
HINWEIS: das speichern wird keinen Einfluss auf Ihre Datenbank. Es ist nur für ein rollback für die Transaktion.
InformationsquelleAutor Dhananjayan K