abel533 / MyBatis-Spring-Boot

Spring Boot集成MyBatis的基础项目
3.37k stars 1.59k forks source link

整合Mapper的时候发生NoSuchMethodException #75

Closed WokringAnt closed 6 years ago

WokringAnt commented 7 years ago
pom.xml
   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
    </parent>

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.3</version>
        </dependency>
<!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>RELEASE</version>
        </dependency>
        <!--mapper-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>RELEASE</version>
        </dependency>
        <!--pagehelper-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>RELEASE</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

··· 调用入口 User user = userMapper.selectByPrimaryKey(1); ···

异常堆栈:
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
    at org.apache.ibatis.builder.annotation.ProviderSqlSource.createSqlSource(ProviderSqlSource.java:135)
    at org.apache.ibatis.builder.annotation.ProviderSqlSource.getBoundSql(ProviderSqlSource.java:103)
    at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:292)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
    ... 34 more
Caused by: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider
    at java.lang.Class.newInstance(Class.java:427)
    at org.apache.ibatis.builder.annotation.ProviderSqlSource.createSqlSource(ProviderSqlSource.java:117)
    ... 45 more
Caused by: java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 46 more
abel533 commented 7 years ago

方法调用过早,由于通用方法还没有被初始化导致的。

WokringAnt commented 7 years ago

没懂起,大神~!

UT 代码如下

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class IntegrationBaseTest {

    @Test
    public void baseTest() {
        assertTrue(true);
    }
}
@MybatisTest
public class UserMapperTest extends IntegrationBaseTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void findById() {
        User user = userMapper.selectByPrimaryKey(1);
        assertNull(user);
    }
}

application.properties

spring.datasource.url=jdbc:h2:mem:canary_test spring.datasource.username=root spring.datasource.password=sa

mybatis

mybatis.type-aliases-package=com.zs.model mybatis.mapper-locations=classpath:mapper/*.xml

mapper

mapper.mappers=com.zs.util.CommonMapper mapper.not-empty=false mapper.identity=H2

page helper configurations

pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql

abel533 commented 7 years ago

MybatisTest 注解的问题。目前没有针对这个注解测试过。

WokringAnt commented 7 years ago

确实是MybatisTest annotation的问题,谢谢

SmileTower commented 7 years ago

@abel533 通用Mapper,没加载好的话,项目总就无法使用 @PostConstruct,求解

SmileTower commented 7 years ago

构造器-->自动注入-->PostConstrut-->InitializingBean-->xml中配置init方法

abel533 commented 7 years ago

确实是没加载好导致的,mybatis 扫描的接口没有完全按照 spring 的处理顺序进行,所以目前没有好的办法处理,最近会考虑换种方式解决这个问题。

SmileTower commented 7 years ago

@abel533 那个mybatis-plus boot 插件好像没这个问题

abel533 commented 7 years ago

后续会提供@MapperScan注解来解决。

springpro commented 6 years ago

同样的问题,目前我是用定义一个_监听器: ApplicationListener - ContextRefreshedEvent 处理的。

liyongjun1 commented 6 years ago

@abel533 如果是使用了数据库的连接池,每一个连接 session ,在使用前都要 registerMapper吗?

liyongjun1 commented 6 years ago

@abel533 这里在跟您请教一下,我这里是非spring 项目,我的SqlSessionFactory 中数据源,session使用了连接池来管理。早上看了一下您的文档想引入过来,发现每一个session在使用前都要 手动注册一遍 通用mapper(mapperHelper.registerMapper(TestUserMapper.class);) 。您那里有没有比较好的解决方案

liyongjun1 commented 6 years ago

@abel533 Sorry , I hv resolved this problem, something was wrong in my code

tuzkimo commented 6 years ago

今天我也遇到了这个问题,后来仔细研究了 abel533 大神的样例,发现 @MapperScan 注解要用 tk.mybatis.spring.annotation.MapperScan,然后就可以了,不知道跟你的情况是不是一样,希望能帮到你

abel533 commented 6 years ago

发生这个问题的时候还没法解决,后续发布的mapper-starter-1.2.0解决了这个问题。

PolkAllen commented 6 years ago

17:09:17,969 ERROR [main]: Application startup failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.github.pagehelper.autoconfigure.MapperAutoConfiguration': Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: tk.mybatis.mapper.mapperhelper.MapperHelper.setConfig(Ltk/mybatis/mapper/entity/Config;)V at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] at cn.mwee.winpos.cloud.admin.service.report.ReportServiceProvider.main(ReportServiceProvider.java:57) [bin/:?] Caused by: java.lang.NoSuchMethodError: tk.mybatis.mapper.mapperhelper.MapperHelper.setConfig(Ltk/mybatis/mapper/entity/Config;)V at com.github.pagehelper.autoconfigure.MapperAutoConfiguration.addPageInterceptor(MapperAutoConfiguration.java:62) ~[mapper-spring-boot-autoconfigure-1.1.1.jar:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_111] at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_111] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] ... 18 more help~~

abel533 commented 6 years ago

@xuboke 用 2.0.0 版本的 mapper-starter 试试

PolkAllen commented 6 years ago

已解决,包冲突导致的,心碎

zhanghuadi commented 6 years ago

image 在启动类中,改成tk......这个包就可以了

littleC-C commented 6 years ago

@abel533 用 2.0.0 版本的 mapper-starter 试试

是指的mapper-spring-boot-starter吗? 我用的版本是2.0.1,也遇到了问题:tk.mybatis.mapper.provider.base.BaseSelectProvider.()

   <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.1</version>
   </dependency>
abel533 commented 6 years ago

换 2.0.2,如果还有问题就先禁用 devtools

JKTerrific commented 6 years ago

如果是使用这种spring配置的话也会出现这个问<bean id="sqlSessionFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 需要将他改成tk的实现,如下:<bean id="sqlSessionFactory" class="tk.mybatis.spring.mapper.MapperScannerConfigurer">

abel533 commented 6 years ago

@JKTerrific 你这个id名字有问题。。

ApocalypseT commented 5 years ago

我也遇到了这种问题Q///Q

wathenjiang commented 4 years ago

我遇到的原因是 @Autowired 和 Mapper 接口一起放到方法入口参数时的报错。 将 Mapper 接口从入口参数改为类的字段就不报错了。

Melodykuang commented 9 months ago

同样的问题,目前我是用定义一个_监听器: ApplicationListener - ContextRefreshedEvent 处理的。

大佬,可以告知如何写的吗,贴一下代码,谢谢了