Grails Webflow - keeping things *out* of flow scope

ぃ、小莉子 提交于 2019-12-06 04:14:37

Refining the above answer instead of clearing the persistenceContext we simply evict the instances as we finish with them, like so:

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

This is still a work-around for not being able to mark the closure variables as transient

The answer to my question is:

the flow object is a map that contains a reference to the "persistenceContext" which is a org.hibernate.impl.SessionImpl so the flow tries to store the entire session, even if the objects are not changed (for context I suppose)

this incorrect example from grails 1.1.x doc gives us a clue what to do:

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

The flow.clear() clears the entire flow map including the persistenceContext or the session, which then makes the whole flow fail due to lack of a session.

so the intermediate "solution" is to use the persistenceContext and in this case clear it. So this works:-

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

The obvious problem with this is that the session is cleared completely, instead of just keeping out things I don't want in the flow.

for want of a better way, here is a generalised solution that removes any non Serializable objects from the persistenceContext of the flow. This could be a service method given the flow:-

def remove = []
flow.persistenceContext.getPersistenceContext().getEntitiesByKey().values().each { entity ->
    if(!entity instanceof Serializable){
        remove.add(entity)
    }
}
remove.each {flow.persistenceContext.evict(it)}

If like me you need to evict all maybe you like to do

flow.persistenceContext.flush()
flow.persistenceContext.persistenceContext.clear()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!