MyBatis-Spring-Boot icon indicating copy to clipboard operation
MyBatis-Spring-Boot copied to clipboard

大神帮忙看下-----只差把这个示例代码 全部copy过去了。

Open helloworldtang opened this issue 7 years ago • 58 comments

错误:Caused by: java.lang.InstantiationException: tk.mybatis.mapper.provider.SpecialProvider at java.lang.Class.newInstance(Class.java:427) at org.apache.ibatis.builder.annotation.ProviderSqlSource.createSqlSource(ProviderSqlSource.java:85) ... 136 common frames omitted Caused by: java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.SpecialProvider.() at java.lang.Class.getConstructor0(Class.java:3082)

相关代码已上传到github:https://github.com/helloworldtang/SpringBootCookbook rest接口:/tx/post 所在class: com.tangcheng.rest.TxController

helloworldtang avatar Mar 27 '17 16:03 helloworldtang

重新切了个分支:v1.0.0_tx 去掉通用mapper,只使用mybatis-spring-boot-starter,就可以正常使用了

helloworldtang avatar Mar 28 '17 02:03 helloworldtang

重新启了一个Module,按照例子中操作了一遍。是ok的 我上面的那个项目中,那个地方的配置干扰了通用Mapper的初始呢? 奇怪

helloworldtang avatar Mar 28 '17 16:03 helloworldtang

上面错误的原因是mapper配置错误,导致通用方法没有被正确的初始化。

abel533 avatar Mar 30 '17 13:03 abel533

@abel533 反复把代码与这个例子比对了一下。没有发现错。跟了下代码,发现执行过程中传的参数都对

但还是报错了:

Error invoking SqlProvider method (tk.mybatis.mapper.provider.SpecialProvider.dynamicSQL). Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.SpecialProvider

报错位置: [ providermethod-dyn

有时间给看看呗,没有找到门道啊 示例代码在项目中的位置: package-mybati-spring

helloworldtang avatar Apr 06 '17 12:04 helloworldtang

@abel533 原来是SpecialProvider.class.newInstance();报错了:

nosuchmethod-2 nosuchmethod-specialprovider

为什么呢?

helloworldtang avatar Apr 06 '17 12:04 helloworldtang

今天在对比代码时发现一个: 上面报错项目中MappedStatement.java中sqlSource是tk.mybatis.mapper.provider.SpecialProvider 你给出的例子中却是org.apache.ibatis.scripting.xmltags.DynamicSqlSource

哪个地方的配置决定实例化哪个SqlSource呢? 有错的: providersqlsource-mybatis

正常的: dynamicsqlsource-mybatis

helloworldtang avatar Apr 07 '17 11:04 helloworldtang

@abel533 Mapper哪个地方配错了呢。和这个例子中除了class名字外,都是一样的呢?

helloworldtang avatar Apr 08 '17 10:04 helloworldtang

ProviderSqlSource 初始化时不会调用 newInstance 方法。当 Mapper 处理所有的通用方法后,都已经不是 ProviderSqlSource 了,永远都没机会调用 newInstance 了。唯一会导致这个错误的原因就是配置错误导致通用方法没被处理。

你接口都集成的 MyMapper,你按文档配置 mappers 属性试试。

abel533 avatar Apr 08 '17 12:04 abel533

@abel533 看看错哪了呢? 又比对了一遍了。都有配置的: mappers: mybatis-config

basepackages

pom-dependency

helloworldtang avatar Apr 08 '17 13:04 helloworldtang

发现一个有意思地方: 我这边 通用mapper自动配置没有生效:

上面例子中spring 容器中有这些bean,我写的那个demo就没有

beans-abel

helloworldtang avatar Apr 08 '17 15:04 helloworldtang

@abel533 感觉这是一个bug,看看是那个方面的原因导致的呢?

问题原因应该是:com.github.pagehelper.autoconfigure.MapperAutoConfiguration和 com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration 没有自动配置。

以MapperAutoConfiguration为例,Spring容器中是有SqlSessionFactory这个实例的,从下面的代码看,MapperAutoConfiguration 是应该会被自动配置,但实际情况是 ----- 没有实例化: @Configuration @ConditionalOnBean({SqlSessionFactory.class}) @EnableConfigurationProperties({MapperProperties.class}) @AutoConfigureAfter({MybatisAutoConfiguration.class}) public class MapperAutoConfiguration {

helloworldtang avatar Apr 08 '17 16:04 helloworldtang

加个 @MapperScan

abel533 avatar Apr 09 '17 01:04 abel533

@abel533 感觉问题出在MapperAutoConfiguration.java的Condition条件上了 看看是不是应该把MapperAutoConfiguration.java上的注解 @ConditionalOnBean({SqlSessionFactory.class}) 改成 @ConditionalOnClass({SqlSessionFactory.class})

MapperScan已经加过了。 @MapperScan放在启动的那个class CookbookApplication.java上了

helloworldtang avatar Apr 09 '17 04:04 helloworldtang

@abel533 这个bug不想跟了。回退到使用java config来配置PageInterceptor和通用Mapper. 现在已经Ok。

tips: 经过这个bug搞的,感觉现在离能写mybatis plugin只差一点点了 ☺^_^

helloworldtang avatar Apr 11 '17 05:04 helloworldtang

@abel533

建议将MapperAutoConfiguration和PageHelperAutoConfiguration的实例化条件改为ConditionalOnClass

应该是spring boot中加载MapperAutoConfiguration和PageHelperAutoConfiguration的时机有差异

spring boot actuator中提供的信息显示,在加载通用Mapper和PageHelper的autoconfig时,SqlSessionFactory.class并没有实例化完成。

conditiononbeansqlfactory

helloworldtang avatar Apr 17 '17 08:04 helloworldtang

我这里的启动日志中:

   MapperAutoConfiguration matched:
      - @ConditionalOnBean (types: org.apache.ibatis.session.SqlSessionFactory; SearchStrategy: all) found bean 'sqlSessionFactory' (OnBeanCondition)

   PageHelperAutoConfiguration matched:
      - @ConditionalOnBean (types: org.apache.ibatis.session.SqlSessionFactory; SearchStrategy: all) found bean 'sqlSessionFactory' (OnBeanCondition)

abel533 avatar Apr 17 '17 13:04 abel533

你使用的 spring boot,以及 pagehelper 和 mapper 的 starter 版本是多少?

abel533 avatar Apr 17 '17 13:04 abel533

@abel533 都是从https://github.com/abel533/MyBatis-Spring-Boot.git copy过去的

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
    <relativePath/>
    <!-- lookup parent from repository -->
</parent>

    <!--mapper-->
    <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper-spring-boot-starter</artifactId>
        <version>1.1.0</version>
    </dependency>
    <!--pagehelper-->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>1.1.0</version>
    </dependency>

helloworldtang avatar Apr 18 '17 02:04 helloworldtang

@abel533 如果单独写一个项目,里面只有https://github.com/abel533/MyBatis-Spring-Boot.git 里面的业务逻辑,也是可以的。

但在https://github.com/helloworldtang/spring-boot-cookbook.git 这个学习用的小项目中,就会not Matched

helloworldtang avatar Apr 18 '17 02:04 helloworldtang

@helloworldtang 遇到同样的问题,你解决了吗?

hellokaton avatar May 12 '17 07:05 hellokaton

现在是能用了,具体什么原因也不清楚。 把相关配置都放在application,properties中就可以。

helloworldtang avatar May 21 '17 01:05 helloworldtang

遇到这个问题了, Caused by: org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseSelectProvider.dynamicSQL).
Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider

我的分析如下: spring boot项目中用的是mybatis的: @MapperScan(basePackages = { "com.xxx.mapper"}) 而传统spring mvc项目中用的是tk.mybatis的: <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xxx.mapper" /> </bean>

spring-boot那种mapper扫描方式,少了一些 tk.mybatis.spring.mapper.MapperScannerConfigurer 中的操作。所以我猜想可能是这个原因导致。

看了很多spring-boot源码和文档,但是后面总结了一下,其实spring-boot并没有像官方说的那样简便易用,特别是涉及一些复杂配置,spring-boot管理起来很乱。所以,我接下来准备尝试把xml和spring mvc的注释方式结合起来使用,不知道效果会怎样。

zollty avatar May 23 '17 06:05 zollty

@zollty 这个错误只有配置错的时候才会出现,就是没有处理通用接口方法导致的。

abel533 avatar May 23 '17 11:05 abel533

@abel533 据我深入分析,这不是配置错误,而是代码问题。@MapperScan注解并不能代替tk.mybatis.spring.mapper.MapperScannerConfigurer,如果用@MapperScan则少了对GenericBeanDefinition的改造、少了加入mapperHelper

为了验证这个说法,我将@MapperScan换成了自己写的@MyMapperScan,扫描注解时加上mapperHelper并对BeanDefinitionRegistry registry进行了处理,自然就解决了这个问题。

建议你提供一个tk.MapperScan,替换Mybatis自带那个。

zollty avatar May 23 '17 14:05 zollty

@zollty 你用mapper-starter了吗?这个项目会自动处理通用接口。

abel533 avatar May 24 '17 14:05 abel533

大神们,有什么解决方案吗?我也遇到了类似的错误,所有的配置都对比了一遍,应该没什么错误,但是BaseSelectProvider初始化就是报错。

fengcbo avatar Jun 09 '17 11:06 fengcbo

@fengcbo 你用的1.1.1版本的starter?

abel533 avatar Jun 10 '17 01:06 abel533

恩,用的是1.1.1版本的。只是在@Configuration中引用Mapper会报错,项目启动完成后就可以正常调用了

fengcbo avatar Jun 10 '17 02:06 fengcbo

@fengcbo 这种情况会在初始化完成前调用,所以会出错。

abel533 avatar Jun 10 '17 08:06 abel533

哪有什么方法可以解决这个问题吗?

fengcbo avatar Jun 10 '17 08:06 fengcbo