mybatis+springboot+flowable6.4.0遇到的問題

前面一大堆都是記錄問題過程,愛看不看。解決辦法再最後。

問題:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

寫錯對應關係 namespace等騷操作造成的就不說了。動動腦子。下面主要說衝突導致的這個問題。
源碼查看:
1 報錯位置

 MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,
          configuration);
      if (ms == null) {
        if (method.getAnnotation(Flush.class) != null) {
          name = null;
          type = SqlCommandType.FLUSH;
        } else {
          throw new BindingException("Invalid bound statement (not found): "
              + mapperInterface.getName() + "." + methodName);
        }
        ...

2 ms爲啥爲空 因爲 mappedStatements裏沒有(MapperLocations配置沒生效)

private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName,
        Class<?> declaringClass, Configuration configuration) {
      String statementId = mapperInterface.getName() + "." + methodName;
      if (configuration.hasStatement(statementId)) {
        return configuration.getMappedStatement(statementId);
      } else if (mapperInterface.equals(declaringClass)) {
        return null;
      }
  public boolean hasStatement(String statementName) {
    return hasStatement(statementName, true);
  }

  public boolean hasStatement(String statementName, boolean validateIncompleteStatements) {
    if (validateIncompleteStatements) {
      buildAllStatements();
    }
    return mappedStatements.containsKey(statementName);
  }

3 真正原因! @ConditionalOnMissingBean !!!!:如果容器中沒有,就注入,如果有就不注入.mybatis的sqlsession被flowable的覆蓋了

mybatis的:org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration裏
@Bean
   @ConditionalOnMissingBean
   public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
  	 ...
   factory.setMapperLocations(this.properties.resolveMapperLocations());
  	...
   }
   
flowable的:org.flowable.ui.modeler.conf.DatabaseConfiguration裏
@Bean
   public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
       SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
       sqlSessionFactoryBean.setDataSource(dataSource);
       String databaseType = this.initDatabaseType(dataSource);
       if (databaseType == null) {
           throw new FlowableException("couldn't deduct database type");
       } else {
           try {
               Properties properties = new Properties();
               properties.put("prefix", this.modelerAppProperties.getDataSourcePrefix());
               properties.put("blobType", "BLOB");
               properties.put("boolValue", "TRUE");
               properties.load(this.getClass().getClassLoader().getResourceAsStream("org/flowable/db/properties/" + databaseType + ".properties"));
               sqlSessionFactoryBean.setConfigurationProperties(properties);
               sqlSessionFactoryBean.setMapperLocations(ResourcePatternUtils.getResourcePatternResolver(this.resourceLoader).getResources("classpath:/META-INF/modeler-mybatis-mappings/*.xml"));
               sqlSessionFactoryBean.afterPropertiesSet();
               return sqlSessionFactoryBean.getObject();
           } catch (Exception var5) {
               throw new FlowableException("Could not create sqlSessionFactory", var5);
           }
       }
   }

4 很明顯,mybatis的配置被覆蓋了。吐槽一下flowable-ui的源碼:臭蟲,都是臭蟲!

解決辦法:就是兼顧 flowable和mybatis的配置.

1 第一步 排除flowable的sqlsession注入:

在@ComponentScan里加入這樣的話。
@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = DatabaseConfiguration.class)

2 第二步 增加flowable的屬性配置等。application.properties裏添加如下配置。加modeler-mybatis-mapping那個

mybatis.mapperLocations=classpath*:mapper/*/*.xml,classpath:/META-INF/modeler-mybatis-mappings/*.xml
#這裏就是配個空。或者配置數據庫用戶名 username也行,不要瞎改哈(這個是查詢前綴-flowable)
mybatis.configuration-properties.prefix =
mybatis.configuration-properties.blobType = BLOB
mybatis.configuration-properties.boolValue = TRUE

3 第三步,做到這直接啓動項目可能會報 act_de_model表找不到等錯誤。再一個@Configuration配置里加入以下bean的注入

@Bean
  public Liquibase liquibase(DataSource dataSource) {
      Liquibase liquibase = null;

      Liquibase var5;
      try {
          DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());
          Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
          database.setDatabaseChangeLogTableName("ACT_DE_" + database.getDatabaseChangeLogTableName());
          database.setDatabaseChangeLogLockTableName("ACT_DE_" + database.getDatabaseChangeLogLockTableName());
          liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);
          liquibase.update("flowable");
          var5 = liquibase;
      } catch (Exception var9) {
          throw new InternalServerErrorException("Error creating liquibase database", var9);
      } finally {
      }
      return var5;
  }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章