【问题标题】:MyBatis Not Persisting Stored Procedure CallMyBatis 不持久化存储过程调用
【发布时间】:2015-11-02 15:27:07
【问题描述】:

我正在将 Spring 4 与 MyBatis 3 一起使用。我在 Oracle 11g 中调用一个存储过程,它处理来自临时表的一堆数据并将数据插入到其他几个表中。存储过程在其中调用 commit。然而,没有任何东西被持久化,没有异常或警告,日志中除了这个之外什么都没有。

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

这是我在映射器文件中的定义

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

界面如下

public interface StagedDataMapper {

    @Async
    void processDirectory();

    List<StageDirectory> getStagedDirectory(long institutionId);

    List<StageAppointment> getStagedAppointment(long institutionId);
}

我尝试过插入、更新、选择,但没有任何效果。

更新:

我发现了一个小错误,但它并没有纠正问题。

更新的映射器文件

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

我可以直接在数据库上运行调用 PKG_DIRECTORY.sp_process_staged_data() 并且效果很好。

更新 2:

这是我的 MyBatis 配置:

@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());
    }

}

还有我的映射器

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

更新 3:

我又尝试了一次,但还是没有运气。考虑放弃 MyBatis 这已成为一个问题。

稍微改变了我的持久性配置

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();
    }

}

将 mybatis 版本从 3.3.0 降到 3.2.8,将 mybatis-spring 从 1.2.3 降到 1.2.2。

映射器看起来像这样:

public interface StagedDataMapper {

    void processDirectory();

    List<StageDirectory> getStagedDirectory(long institutionId);

    List<StageAppointment> getStagedAppointment(long institutionId);
}

控制器方法

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

【问题讨论】:

  • 为什么投反对票?这个问题有什么问题?

标签: java spring mybatis java-stored-procedures spring-mybatis


【解决方案1】:

这是一个很老的问题,但没有明显的答案。 换个方式

<select ... </select>;

<update ... </update>

这表明 MyBatis 尊重交易行为。

【讨论】:

    【解决方案2】:

    MyBatis 似乎回滚了所有不是显式 UPDATE 或 DELETE 的查询。

    对我来说,解决方案是将属性 commitRequired="true" 添加到 .不知道这如何转化为您的情况,但似乎是同样的问题。

    来自 LSC-Project 的示例(使用 MyBatis):

      <transactionManager type="JDBC" commitRequired="true">
        <dataSource type="SIMPLE">
          <property value="${driver}" name="JDBC.Driver" />
          <property value="${url}" name="JDBC.ConnectionURL" />
          <property value="${username}" name="JDBC.Username"/>
          <property value="${password}" name="JDBC.Password"/>
          <property value="15" name="Pool.MaximumActiveConnections"/>
          <property value="15" name="Pool.MaximumIdleConnections"/>
          <property value="1000" name="Pool.MaximumWait"/>
        </dataSource>
      </transactionManager>
    

    【讨论】:

      【解决方案3】:

      不知道是什么,但以下工作

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

      这不是

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

      【讨论】:

        猜你喜欢
        • 2018-03-05
        • 2013-03-18
        • 1970-01-01
        • 1970-01-01
        • 2014-05-26
        • 2015-06-19
        • 2011-01-05
        • 2021-10-31
        • 2020-02-24
        相关资源
        最近更新 更多