2011-10-03 30 views
5

Esta es mi configuración de paso. Mis oyentes de omisión en el métodoSkipInWrite() se llaman correctamente. Pero onSkipInRead() no se está llamando. Encontré esto al arrojar deliberadamente una excepción de puntero nulo de mi lector.Spring Batch SkipListener no se llama cuando se produce una excepción en el lector

<step id="callService" next="writeUsersAndResources"> 
     <tasklet allow-start-if-complete="true"> 
      <chunk reader="Reader" writer="Writer" 
       commit-interval="10" skip-limit="10"> 
       <skippable-exception-classes> 
        <include class="java.lang.Exception" /> 
       </skippable-exception-classes> 
      </chunk> 
      <listeners> 
       <listener ref="skipListener" /> 
      </listeners> 
     </tasklet> 
    </step> 

He leído algunos foros e intercambiaron los oyentes-tag en ambos niveles: En el interior del trozo, y fuera de la tasklet. Nada está trabajando ...

Adición de mi oyente salto aquí

package com.legal.batch.core; 

import org.apache.commons.lang.StringEscapeUtils; 
import org.springframework.batch.core.SkipListener; 
import org.springframework.jdbc.core.JdbcTemplate; 


public class SkipListener implements SkipListener<Object, Object> { 


    @Override 
    public void onSkipInProcess(Object arg0, Throwable arg1) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onSkipInRead(Throwable arg0) { 
    } 

    @Override 
    public void onSkipInWrite(Object arg0, Throwable arg1) { 
} 

} 

Expertos sugieren favor

+0

puede también puesto su configuración e implementación de bean "skipListener"? ¿Está implementando la interfaz 'SkipListener '? ¿Estás usando la anotación '@ OnSkipInRead'? etc. – tolitius

+0

Agregué el oyente de omisión aquí – Shiv

Respuesta

8

oyentes Omitir respetan límite de la transacción, lo que significa que siempre se puede llamar justo antes de la transacción se confirma.

Dado que un intervalo de confirmación en su ejemplo se establece en "10", el onSkipInRead se llamará justo en el momento de confirmar estos 10 elementos (a la vez).

Por lo tanto, si intenta realizar una depuración paso a paso, no verá un onSkipInRead llamado inmediatamente después de que un lector de elementos arroje una excepción.

En su ejemplo, SkipListener tiene un método onSkipInRead vacío. Intente agregar algo de registro dentro de onSkipInRead, mueva a y vuelva a ejecutar su trabajo para ver esos mensajes.

EDITAR:

Aquí está un ejemplo de trabajo [nombres se cambian a 'abc']:

<step id="abcStep" xmlns="http://www.springframework.org/schema/batch"> 
    <tasklet> 
     <chunk writer="abcWriter" 
       reader="abcReader" 
       commit-interval="${abc.commit.interval}" 
       skip-limit="1000" > 

      <skippable-exception-classes> 
       <include class="com.abc....persistence.mapping.exception.AbcMappingException"/> 
       <include class="org.springframework.batch.item.validator.ValidationException"/> 
       ... 
       <include class="...Exception"/> 
      </skippable-exception-classes> 

      <listeners> 
       <listener ref="abcSkipListener"/> 
      </listeners> 

     </chunk> 

     <listeners> 
      <listener ref="abcStepListener"/> 
      <listener ref="afterStepStatsListener"/> 
     </listeners> 

     <no-rollback-exception-classes> 
      <include class="com.abc....persistence.mapping.exception.AbcMappingException"/> 
      <include class="org.springframework.batch.item.validator.ValidationException"/> 
      ... 
      <include class="...Exception"/> 
     </no-rollback-exception-classes> 

     <transaction-attributes isolation="READ_COMMITTED" 
           propagation="REQUIRED"/> 
    </tasklet> 
</step> 

donde un grano de abcSkipListener es:

public class AbcSkipListener { 

    private static final Logger logger = LoggerFactory.getLogger("abc-skip-listener"); 

    @OnReadError 
    public void houstonWeHaveAProblemOnRead(Exception problem) { 
     // ... 
    } 


    @OnSkipInWrite 
    public void houstonWeHaveAProblemOnWrite(AbcHolder abcHolder, Throwable problem) { 
     // ... 
    } 

    .... 
} 
+0

Gracias ... Tenía un código sysout dentro deSkipInRead(). Además, estoy lanzando una nueva nullPointerException desde la primera línea de mi lector. Vi en el registro que se superó el límite de omisión de 10 y luego esperaba que se imprimiera el sysout en mi lectura de omisión. Pero no lo veo Intenté poner a los oyentes fuera del tasklet. Sin suerte ... – Shiv

+1

aquí hay un ejemplo de trabajo de uno de mis proyectos en el pasado. Intenta usar '@ OnReadError' en un detector de omisiones. – tolitius

+0

gracias. volveré ... – Shiv

Cuestiones relacionadas