我错过了什么......
我有一个Grails webflow,如下所示: -
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是可序列化的。但我得到这个错误: -
Caused by: java.io.NotSerializableException: com.nerderg.groupie.donate.Target
由于某种原因,Target.list()。每个{}闭包内的“target”对象被放入流量范围,我无法弄清楚如何将其标记为瞬态。
我在服务中有一些代码,当我不想要它们时,它们将对象放在流程范围内。
如何在放入流量范围的闭包中停止局部瞬态变量?
答案 0 :(得分:3)
改进上面的答案而不是清除persistenceContext,我们只是在完成它们时逐出这些实例,如下所示:
Target.list().each {
targets.add(new TargetCommand(name: it.name, id: it.id))
flow.persistenceContext.evict(it)
}
这仍然是无法将闭包变量标记为瞬态
的解决方法答案 1 :(得分:2)
我的问题的答案是:
流对象是一个包含对“persistenceContext”的引用的映射,它是一个org.hibernate.impl.SessionImpl,因此即使对象没有被更改,流也会尝试存储整个会话(对于上下文,我想是)
grails 1.1.x doc中的不正确的示例为我们提供了一条线索:
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"
}
flow.clear()清除整个流程图,包括persistenceContext或会话,然后由于缺少会话而使整个流程失败。
所以中间“解决方案”是使用persistenceContext,在这种情况下清除它。这样可行: -
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'
}
这个问题的一个明显问题是会话被彻底清除,而不是仅仅保留流程中我不想要的东西。
答案 2 :(得分:0)
由于缺少更好的方法,这里是一个通用的解决方案,它从流的persistenceContext中删除任何非Serializable对象。这可以是给定流程的服务方法: -
def remove = []
flow.persistenceContext.getPersistenceContext().getEntitiesByKey().values().each { entity ->
if(!entity instanceof Serializable){
remove.add(entity)
}
}
remove.each {flow.persistenceContext.evict(it)}
答案 3 :(得分:0)
如果像我一样你需要驱逐所有你想做的事
flow.persistenceContext.flush()
flow.persistenceContext.persistenceContext.clear()