Spring batch job repository configuration for WebSphere and Oracle

  1. Introduction
  2. Job Repository configuration

Introduction

This article describes a problem with using the default Spring Batch Job Repository configuration deployed on the WebSphere application server backed by the Oracle database. The following is the exception you may encounter:

org.springframework.dao.DataAccessResourceFailureException: Could not create Oracle LOB
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Couldn't initialize OracleLobHandler because Oracle driver classes are not available. Note that OracleLobHandler requires Oracle JDBC driver 9i or higher!; nested exception is java.lang.ClassNotFoundException: oracle.sql.BLOB
Caused by: java.lang.ClassNotFoundException: oracle.sql.BLOB

This issue is documented on the IBM support website.

Configuration

Proper solution is to configure lob-handler dependency of the Job Repository and inject the OracleLobHandler bean.

To support WebSphere lobHandler bean needs to be instantiated with appropriate nativeJdbcExtractor that is supported by WebSphere.

The following snippet shows Job Repository configuration details

<batch:job-repository id="jobRepository" 
    data-source="dataSource" 
    transaction-manager="transactionManager" 
    lob-handler="lobHandler" />

<bean id="lobHandler" 
    class="org.springframework.jdbc.support.lob.OracleLobHandler">
    <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor" />
</bean>

<bean id="nativeJdbcExtractor"
    class="org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor" />

Data source configuration

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/DS_NAME" />
    <property name="lookupOnStartup" value="true" />
    <property name="cache" value="true" />
    <property name="proxyInterface" value="javax.sql.DataSource" />
</bean>

Transaction manager configuration

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" primary="true">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>