MyBatis 不持久存储过程调用
MyBatis Not Persisting Stored Procedure Call
我正在使用 Spring 4 和 MyBatis 3。我在 Oracle 11g 中调用一个存储过程,它处理来自暂存区的一堆数据 table 并将数据插入其他几个 table秒。存储过程在其中调用提交。然而,没有任何东西被持久化,没有异常或警告,日志中除了这个什么都没有。
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,没有任何效果。
更新:
我发现了一个小错误,但它并没有解决这个问题。
更新映射器文件
<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);
}
不确定是什么,但下面的方法有效
<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>
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>
一个很老的问题,但是没有明显的答案。
只是改变
<select ... </select>;
至
<update ... </update>
这表明 MyBatis 尊重事务行为。
我正在使用 Spring 4 和 MyBatis 3。我在 Oracle 11g 中调用一个存储过程,它处理来自暂存区的一堆数据 table 并将数据插入其他几个 table秒。存储过程在其中调用提交。然而,没有任何东西被持久化,没有异常或警告,日志中除了这个什么都没有。
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,没有任何效果。
更新:
我发现了一个小错误,但它并没有解决这个问题。
更新映射器文件
<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);
}
不确定是什么,但下面的方法有效
<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>
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>
一个很老的问题,但是没有明显的答案。 只是改变
<select ... </select>;
至
<update ... </update>
这表明 MyBatis 尊重事务行为。