Grails Webflow - 保持*流量范围*

时间:2009-11-07 03:15:36

标签: grails spring-webflow

我错过了什么......

我有一个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”对象被放入流量范围,我无法弄清楚如何将其标记为瞬态。

我在服务中有一些代码,当我不想要它们时,它们将对象放在流程范围内。

如何在放入流量范围的闭包中停止局部瞬态变量?

4 个答案:

答案 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()