Grails Webflow - halten Dinge * out * Strömungs Rahmen
-
18-09-2019 - |
Frage
Ich bin etwas fehlt ....
Ich habe eine Grails Webflow der wie folgt aussieht: -
def childFlow = {
start {
action {
def targets = []
Target.list().each {target ->
targets.add(new TargetCommand(name: target.name, id: target.id))
}
log.debug "targets are $targets"
[children: targets]
}
on('success').to('selectChild')
}
...
TargetCommand ist serializable. aber ich bekomme diese Fehlermeldung: -
Caused by: java.io.NotSerializableException: com.nerderg.groupie.donate.Target
Aus irgendeinem Grund das „Ziel“ Objekt, das im Inneren des Target.list ist (). Jede {} Schließung wird immer in den Fluss Rahmen setzen, und ich kann nicht herausfinden, wie es als vorübergehende zu markieren.
Ich habe einige Codes in einem Dienst, die Objekte platziert in Strömungs Umfang hat, wenn ich sie nicht will auch.
Wie kann ich lokale transiente Variablen in Schließungen werden in Strömungs Umfang stoppen setzen?
Lösung
die obige Antwort anstelle des Löschens des PersistenceContext Refining vertreiben wir einfach die Instanzen, wie wir mit ihnen fertig sind, etwa so:
Target.list().each {
targets.add(new TargetCommand(name: it.name, id: it.id))
flow.persistenceContext.evict(it)
}
Dies ist immer noch ein work-around für nicht in der Lage, die Stilllegungs Variablen als transiente zu markieren
Andere Tipps
Die Antwort auf meine Frage ist:
das Flußobjekt ist eine Karte, die einen Verweis auf die „PersistenceContext“, die eine org.hibernate.impl.SessionImpl ist enthält, so dass die Strömung die gesamte Sitzung zu speichern versucht, auch wenn die Objekte nicht geändert werden (für Kontext Ich nehme an )
Dieses falsch Beispiel von Grails 1.1.x doc gibt uns einen Hinweis, was zu tun:
processPurchaseOrder {
action {
def a = flow.address
def p = flow.person
def pd = flow.paymentDetails
def cartItems = flow.cartItems
flow.clear()
def o = new Order(person:p, shippingAddress:a, paymentDetails:pd)
o.invoiceNumber = new Random().nextInt(9999999) cartItems.each { o.addToItems(it) }
o.save()
[order:o] }
on("error").to "confirmPurchase"
on(Exception).to "confirmPurchase"
on("success").to "displayInvoice"
}
Die flow.clear () löscht die gesamte Fluss Karte einschließlich den PersistenceContext oder die Sitzung, die dann die ganze Strömung macht scheitern an einer Sitzung.
so die Zwischen „Lösung“ ist es, die PersistenceContext und in diesem Fall klar, es zu benutzen. So funktioniert das: -
def childFlow = {
start {
action {
sponsorService.updateTargetsFromTaggedContent()
def targets = []
Target.list().each {
targets.add(new TargetCommand(name: it.name, id: it.id))
}
flow.persistenceContext.clear()
[children: targets]
}
on('success').to('selectChild')
on(Exception).to 'finish'
}
Das offensichtliche Problem dabei ist, dass die Sitzung vollständig gelöscht wird, statt nur die Dinge zu halten heraus will ich nicht in der Strömung.
Ermangelung eines besseren Weg, hier ist eine allgemeine Lösung, die alle nicht Serializable Objekte aus dem PersistenceContext der Strömung entfernt. Dies könnte eine Service-Methode den Fluss gegeben werden: -
def remove = []
flow.persistenceContext.getPersistenceContext().getEntitiesByKey().values().each { entity ->
if(!entity instanceof Serializable){
remove.add(entity)
}
}
remove.each {flow.persistenceContext.evict(it)}
Wenn Sie wie ich Sie müssen alle gewaltsam zu vertreiben vielleicht möchten Sie tun
flow.persistenceContext.flush()
flow.persistenceContext.persistenceContext.clear()