3

我错过了一些东西......

我有一个看起来像这样的 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().each {} 闭包内的“目标”对象被放入流范围内,我不知道如何将其标记为瞬态。

当我不希望它们也放置在流范围中时,我在服务中有一些代码。

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

4

4 回答 4

3

完善上面的答案而不是清除persistenceContext,我们只是在完成它们时驱逐实例,如下所示:

    Target.list().each {
        targets.add(new TargetCommand(name: it.name, id: it.id))
        flow.persistenceContext.evict(it)
    }

这仍然是无法将闭包变量标记为瞬态的解决方法

于 2009-11-07T07:25:17.753 回答
2

我的问题的答案是:

流对象是一个映射,其中包含对“persistenceContext”的引用,它是一个 org.hibernate.impl.SessionImpl,因此流尝试存储整个会话,即使对象没有更改(我想是上下文)

grails 1.1.x 文档中的这个不正确的例子给了我们一个线索:

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'
        }

明显的问题是会话被完全清除,而不是仅仅将我不想要的东西排除在流程中。

于 2009-11-07T07:12:37.483 回答
0

为了想要更好的方法,这里是一个通用的解决方案,它从流的持久化上下文中删除任何不可序列化的对象。给定流程,这可能是一种服务方法:-

def remove = []
flow.persistenceContext.getPersistenceContext().getEntitiesByKey().values().each { entity ->
    if(!entity instanceof Serializable){
        remove.add(entity)
    }
}
remove.each {flow.persistenceContext.evict(it)}
于 2009-11-07T09:58:41.537 回答
0

如果像我一样你需要驱逐所有可能你喜欢做的事

flow.persistenceContext.flush()
flow.persistenceContext.persistenceContext.clear()
于 2012-10-18T09:43:32.960 回答