qwe857359351a opened a new issue #2399: 单元测试分 
NullPointerException,ShardingPreparedStatement.executeUpdate
URL: https://github.com/apache/incubator-shardingsphere/issues/2399
 
 
   版本:3.1.0
   
使用单元测试时NullPointerException异常,出现在ShardingPreparedStatement.executeUpdate方法中调用的sqlRoute方法,分库策略使用的是自定义分库策略。
   
   配置如下:
   `#配置多数据源和默认数据源
   sharding.jdbc.datasource.names=ds_0,ds_1
   sharding.jdbc.config.sharding.default-data-source-name=ds_0
   
   
   sharding.jdbc.datasource.ds_0.type=com.alibaba.druid.pool.DruidDataSource
   sharding.jdbc.datasource.ds_0.driver-class-name=com.mysql.jdbc.Driver
   
sharding.jdbc.datasource.ds_0.url=jdbc:mysql://127.0.0.1:3306/sharding_1?useUnicode=true&characterEncoding=UTF-8
   sharding.jdbc.datasource.ds_0.username=root
   sharding.jdbc.datasource.ds_0.password=
   sharding.jdbc.datasource.ds_0.initialSize=10
   sharding.jdbc.datasource.ds_0.minIdle=10
   sharding.jdbc.datasource.ds_0.maxActive=50
   sharding.jdbc.datasource.ds_0.maxWait=60000
   sharding.jdbc.datasource.ds_0.timeBetweenEvictionRunsMillis=60000
   sharding.jdbc.datasource.ds_0.minEvictableIdleTimeMillis=300000
   sharding.jdbc.datasource.ds_0.validationQuery=SELECT 'x'
   sharding.jdbc.datasource.ds_0.testWhileIdle=true
   sharding.jdbc.datasource.ds_0.testOnBorrow=false
   sharding.jdbc.datasource.ds_0.testOnReturn=false
   sharding.jdbc.datasource.ds_0.poolPreparedStatements=true
   sharding.jdbc.datasource.ds_0.maxPoolPreparedStatementPerConnectionSize=20
   sharding.jdbc.datasource.ds_0.filters=wall,stat
   
   sharding.jdbc.datasource.ds_1.type=com.alibaba.druid.pool.DruidDataSource
   sharding.jdbc.datasource.ds_1.driver-class-name=com.mysql.jdbc.Driver
   
sharding.jdbc.datasource.ds_1.url=jdbc:mysql://127.0.0.1:3306/sharding_2?useUnicode=true&characterEncoding=UTF-8
   sharding.jdbc.datasource.ds_1.username=root
   sharding.jdbc.datasource.ds_1.password=
   sharding.jdbc.datasource.ds_1.initialSize=10
   sharding.jdbc.datasource.ds_1.minIdle=10
   sharding.jdbc.datasource.ds_1.maxActive=50
   sharding.jdbc.datasource.ds_1.maxWait=60000
   sharding.jdbc.datasource.ds_1.timeBetweenEvictionRunsMillis=60000
   sharding.jdbc.datasource.ds_1.minEvictableIdleTimeMillis=300000
   sharding.jdbc.datasource.ds_1.validationQuery=SELECT 'x'
   sharding.jdbc.datasource.ds_1.testWhileIdle=true
   sharding.jdbc.datasource.ds_1.testOnBorrow=false
   sharding.jdbc.datasource.ds_1.testOnReturn=false
   sharding.jdbc.datasource.ds_1.poolPreparedStatements=true
   sharding.jdbc.datasource.ds_1.maxPoolPreparedStatementPerConnectionSize=20
   sharding.jdbc.datasource.ds_1.filters=wall,stat
   
   
   #自定义策略使用userId分库
   
sharding.jdbc.config.sharding.tables.sharding_user.database-strategy.standard.sharding-column=userId
   
sharding.jdbc.config.sharding.tables.sharding_user.database-strategy.standard.precise-algorithm-class-name=com.site.parent.datasource.rules.UserDataSourceStrategy
   `
   
   单元测试
   `
       @Test
       public void testShardingTable() {
           String insertSql = "insert into sharding_user(userId,age) values(?, 
?)";
           jdbcTemplate.update(insertSql, System.currentTimeMillis(), 1);
           System.out.println("分库分表保存成功");
       }
   `
   
   分库策略
   `
           //此行日志会输出
           logger.info("分库操作,当前库有:" + JSON.toJSONString(availableTargetNames));
   
           //通过debug,userId是有值的,不是空
           Integer userId = shardingValue.getValue();
   
           //这里开始就不执行了,没有输出日志
           logger.info("分库操作,当前shardingValue为:" + userId);
           String end = "_" + (userId % 2);
           for (String name : availableTargetNames) {
               if (name.endsWith(end)) {
                   logger.info("user要存入的库为:" + name);
                   return name;
               }
           }
           throw new RuntimeException("分库失败");
   `
   
   如上代码,在分库策略中能获取到userId的值,不是空,但是不会再执行下方的分库计算代码,而是直接跳到
   `
   try {
               clearPrevious();
               sqlRoute();
               initPreparedStatementExecutor();
               return preparedStatementExecutor.executeUpdate();
           } finally {
               //跳到了这里,routeResult为空
               refreshTableMetaData(connection.getShardingContext(), 
routeResult.getSqlStatement());
               clearBatch();
           }
   `
   
   请问为什么会出现这样的情况,为什么计算分库的代码不会执行,而是直接报异常?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to