javaspringmybatisjava-stored-proceduresspring-mybatis

MyBatis Not Persisting Stored Procedure Call


I am using Spring 4 with MyBatis 3. I am calling a stored procedure in Oracle 11g which processes a bunch of data from a staging table and inserts the data into several other tables. The stored procedure calls commit inside it. However nothing is being persisted, there are no exceptions or warnings, nothing in the logs except this.

11:59:48.297 DEBUG BaseJdbcLogger.debug - ==>  Preparing: {call PKG_DIRECTORY.sp_process_staged_data} 
11:59:48.318 DEBUG BaseJdbcLogger.debug - ==> Parameters: 

Here is my definition in my mapper file

<insert id="processDirectory" statementType="CALLABLE">
    {call PKG_DIRECTORY.sp_process_staged_data}
</insert>

Here is the interface

public interface StagedDataMapper {

    @Async
    void processDirectory();

    List<StageDirectory> getStagedDirectory(long institutionId);

    List<StageAppointment> getStagedAppointment(long institutionId);
}

I've tried insert, update, select, nothing works.

UPDATE:

I found a tiny mistake however it did not correct the issue.

Updated mapper file

<select id="processDirectory" statementType="CALLABLE">
    {call PKG_DIRECTORY.sp_process_staged_data()}
</select>

I can run call PKG_DIRECTORY.sp_process_staged_data() on the database directly and it works just fine.

Update 2:

Here is my MyBatis config:

@Configuration
public class PersistenceConfig {

    @Autowired
    Environment environment;

    @Bean(name = "datasource")
    public ComboPooledDataSource dataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(environment.getRequiredProperty("c3p0.driver"));
        dataSource.setJdbcUrl(environment.getRequiredProperty("c3p0.url"));
        dataSource.setUser(environment.getRequiredProperty("c3p0.user"));
        dataSource.setPassword(environment.getRequiredProperty("c3p0.password"));
        dataSource.setInitialPoolSize(environment.getRequiredProperty("c3p0.initialPoolSize", Integer.class));
        dataSource.setMaxPoolSize(environment.getRequiredProperty("c3p0.maxPoolSize", Integer.class));
        dataSource.setMinPoolSize(environment.getRequiredProperty("c3p0.minPoolSize", Integer.class));
        dataSource.setAcquireIncrement(environment.getRequiredProperty("c3p0.acquireIncrement", Integer.class));
        dataSource.setMaxStatements(environment.getRequiredProperty("c3p0.maxStatements", Integer.class));
        dataSource.setMaxIdleTime(environment.getRequiredProperty("c3p0.maxIdleTime", Integer.class));
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage("org.something.core.domain");
        return sessionFactory.getObject();
    }

    @Bean(name = "transactionManager")
    public DataSourceTransactionManager dataSourceTransactionManager() throws PropertyVetoException{
        return new DataSourceTransactionManager(dataSource());
    }

}

And my mapper

<insert id="processDirectory" statementType="CALLABLE">
    {CALL PKG_DIRECTORY.SP_PROCESS_STAGED_DATA()}
</insert>

Update 3:

I made another attempt but still no luck. Thinking about ditching MyBatis this is becoming such an issue.

Changed my persistence config a bit

public class PersistenceConfig {

    @Autowired
    Environment environment;

    @Bean(name = "datasource")
    public ComboPooledDataSource dataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(environment.getRequiredProperty("c3p0.driver"));
        dataSource.setJdbcUrl(environment.getRequiredProperty("c3p0.url"));
        dataSource.setUser(environment.getRequiredProperty("c3p0.user"));
        dataSource.setPassword(environment.getRequiredProperty("c3p0.password"));
        dataSource.setInitialPoolSize(environment.getRequiredProperty("c3p0.initialPoolSize", Integer.class));
        dataSource.setMaxPoolSize(environment.getRequiredProperty("c3p0.maxPoolSize", Integer.class));
        dataSource.setMinPoolSize(environment.getRequiredProperty("c3p0.minPoolSize", Integer.class));
        dataSource.setAcquireIncrement(environment.getRequiredProperty("c3p0.acquireIncrement", Integer.class));
        dataSource.setMaxStatements(environment.getRequiredProperty("c3p0.maxStatements", Integer.class));
        dataSource.setMaxIdleTime(environment.getRequiredProperty("c3p0.maxIdleTime", Integer.class));
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage("org.something.core.domain");
        sessionFactory.setTransactionFactory(springManagedTransactionFactory());
        return sessionFactory.getObject();
    }

    @Bean(name = "transactionManager")
    public DataSourceTransactionManager dataSourceTransactionManager() throws PropertyVetoException{
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public SpringManagedTransactionFactory springManagedTransactionFactory() {
        return new SpringManagedTransactionFactory();
    }

}

Rolled mybatis version from 3.3.0 down to 3.2.8 and mybatis-spring from 1.2.3 down to 1.2.2.

Mapper looks like this:

public interface StagedDataMapper {

    void processDirectory();

    List<StageDirectory> getStagedDirectory(long institutionId);

    List<StageAppointment> getStagedAppointment(long institutionId);
}

Controller method

@Transactional
    @RequestMapping(value = "/directory/process", method = RequestMethod.POST)
    public ResponseEntity processStagedDirectory() {
        stagedDataMapper.processDirectory();
        return new ResponseEntity(HttpStatus.ACCEPTED);
    }

Solution

  • Not sure what but the following works

    <insert id="processDirectory" statementType="CALLABLE">
        <![CDATA[{ CALL PKG_DIRECTORY.SP_PROCESS_STAGED_DATA() }]]>
    </insert>
    

    This does not

    <insert id="processDirectory" statementType="CALLABLE">
        { CALL PKG_DIRECTORY.SP_PROCESS_STAGED_DATA() }
    </insert>