문제

뭔가 빠졌네요....

다음과 같은 Grails 웹플로가 있습니다.

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 {} 클로저 내부에 있는 "대상" 객체가 흐름 범위에 들어가고 있으며 이를 임시로 표시하는 방법을 알 수 없습니다.

원하지 않을 때 흐름 범위에 개체가 배치된 서비스에 일부 코드가 있습니다.

흐름 범위에 배치되는 클로저의 로컬 임시 변수를 어떻게 중지합니까?

도움이 되었습니까?

해결책

persistenceContext를 지우는 대신 위의 답변을 구체화하여 다음과 같이 인스턴스를 완료할 때 간단히 인스턴스를 제거합니다.

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

이는 클로저 변수를 일시적인 것으로 표시할 수 없는 해결 방법입니다.

다른 팁

내 질문에 대한 답은 다음과 같습니다.

Flow 객체는 org.hibernate.impl.sessionimpl 인 "persistencecontext"에 대한 참조를 포함하는 맵입니다. 따라서 객체가 변경되지 않더라도 흐름이 전체 세션을 저장하려고합니다 (컨텍스트를 위해).

이것 잘못된 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'
        }

이것의 명백한 문제는 흐름에서 원하지 않는 것들을 막는 대신 세션이 완전히 지워진다는 것입니다.

더 나은 방법을 원하기 위해, 여기에는 흐름의 영구 콘텍스트에서 직렬화 할 수없는 객체를 제거하는 일반화 된 솔루션이 있습니다. 이것은 흐름을 감안할 때 서비스 방법 일 수 있습니다.

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

나를 좋아한다면 당신은 아마 당신이 좋아하는 모든 것을 퇴거해야합니다

flow.persistenceContext.flush()
flow.persistenceContext.persistenceContext.clear()
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top