SweetInk / jrebel-mybatisplus

A hook plugin for Support MybatisPlus that reloads modified SQL maps.
MIT License
171 stars 32 forks source link

mp3.4.2+2021.3.2jrebel无法启动 #22

Closed jamie9762 closed 2 years ago

jamie9762 commented 2 years ago

org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource:

SweetInk commented 2 years ago

我这边测试没有任何问题,请提供更详细的日志,以及环境信息

SweetInk commented 2 years ago

问题解决了吗,我看你关了这个Issue

jamie9762 commented 2 years ago

image 用插件启动会调用这个方法2次,而且是在xml中没有定义的方法,像用了@Select注解实现的就不行

SweetInk commented 2 years ago

把完整的异常堆栈发出来看下吧

jamie9762 commented 2 years ago

Caused by: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.mapper.TestMapper.insert. please check com/mapper/TestMapper.java (best guess) and com/mapper/TestMapper.java (best guess) at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:1014) at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:970) at com.baomidou.mybatisplus.core.MybatisConfiguration.addMappedStatement(MybatisConfiguration.java:44002) at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:297) at com.baomidou.mybatisplus.core.injector.AbstractMethod.addMappedStatement(AbstractMethod.java:363) at com.baomidou.mybatisplus.core.injector.AbstractMethod.addInsertMappedStatement(AbstractMethod.java:305) at com.baomidou.mybatisplus.core.injector.methods.Insert.injectMappedStatement(Insert.java:67) at com.baomidou.mybatisplus.core.injector.AbstractMethod.inject(AbstractMethod.java:73) at com.baomidou.mybatisplus.core.injector.AbstractSqlInjector.lambda$inspectInject$0(AbstractSqlInjector.java:55) at java.util.ArrayList.forEach(ArrayList.java:1259) at com.baomidou.mybatisplus.core.injector.AbstractSqlInjector.inspectInject(AbstractSqlInjector.java:55) at com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder.parserInjector(MybatisMapperAnnotationBuilder.java:133) at com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder.parse(MybatisMapperAnnotationBuilder.java:123) at com.baomidou.mybatisplus.core.MybatisMapperRegistry.addMapper(MybatisMapperRegistry.java:83) at com.baomidou.mybatisplus.core.MybatisConfiguration.addMapper(MybatisConfiguration.java:102) at org.apache.ibatis.builder.xml.XMLMapperBuilder.bindMapperForNamespace(XMLMapperBuilder.java:432) at org.apache.ibatis.builder.xml.XMLMapperBuilder.parse(XMLMapperBuilder.java:97) at com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean.buildSqlSessionFactory(MybatisSqlSessionFactoryBean.java:593) ... 86 common frames ˙

我创建了新的空项目,确实可以运行,旧工程依然报错

jamie9762 commented 2 years ago

问题解决了吗,我看你关了这个Issue

晕死,公司有人重写了MybatisConfiguration,导致跟MP版本对不上...好无语...

SweetInk commented 2 years ago

问题解决了吗,我看你关了这个Issue

晕死,公司有人重写了MybatisConfiguration,导致跟MP版本对不上...好无语...

贴一下重写后的MybatisConfiguration代码,你上面的那个异常貌似是TestMapper.java对应的xml有两个insert方法,方便的话也贴一下代码。

jamie9762 commented 2 years ago
/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.core;

import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.executor.MybatisCachingExecutor;
import com.baomidou.mybatisplus.core.executor.MybatisReuseExecutor;
import com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import lombok.Getter;
import lombok.Setter;

import org.apache.ibatis.binding.MapperRegistry;
import org.apache.ibatis.executor.BatchExecutor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.transaction.Transaction;

/**
 * replace default Configuration class
 * <p>Caratacus 2016/9/25 replace mapperRegistry</p>
 *
 * @author hubin
 * @since 2016-01-23
 */
public class MybatisConfiguration extends Configuration {

    /**
     * Mapper 注册
     */
    protected final MybatisMapperRegistry mybatisMapperRegistry = new MybatisMapperRegistry(this);

    public MybatisConfiguration(Environment environment) {
        this();
        this.environment = environment;
    }

    @Setter
    @Getter
    private GlobalConfig globalConfig = GlobalConfigUtils.defaults();

    /**
     * 初始化调用
     */
    public MybatisConfiguration() {
        super();
        this.mapUnderscoreToCamelCase = true;
        languageRegistry.setDefaultDriverClass(MybatisXMLLanguageDriver.class);
    }

    /**
     * MybatisPlus 加载 SQL 顺序:
     * <p>1、加载XML中的SQL</p>
     * <p>2、加载sqlProvider中的SQL</p>
     * <p>3、xmlSql 与 sqlProvider不能包含相同的SQL</p>
     * <p>调整后的SQL优先级:xmlSql > sqlProvider > curdSql</p>
     */
    @Override
    public void addMappedStatement(MappedStatement ms) {
        // log.info("id={},userCache = {},cache={}",ms.getId(),ms.isUseCache(),ms.getCache());
        if (mappedStatements.containsKey(ms.getId())) {
            /*
             * 说明已加载了xml中的节点; 忽略mapper中的SqlProvider数据
             */
            //log.info("mapper[" + ms.getId() + "] is ignored, because it exists, maybe from xml file");
            return;
        }
        super.addMappedStatement(ms);
    }

    /**
     * 使用自己的 MybatisMapperRegistry
     */
    @Override
    public MapperRegistry getMapperRegistry() {
        return mybatisMapperRegistry;
    }

    /**
     * 使用自己的 MybatisMapperRegistry
     */
    @Override
    public <T> void addMapper(Class<T> type) {
        mybatisMapperRegistry.addMapper(type);
    }

    /**
     * 使用自己的 MybatisMapperRegistry
     */
    @Override
    public void addMappers(String packageName, Class<?> superType) {
        mybatisMapperRegistry.addMappers(packageName, superType);
    }

    /**
     * 使用自己的 MybatisMapperRegistry
     */
    @Override
    public void addMappers(String packageName) {
        mybatisMapperRegistry.addMappers(packageName);
    }

    /**
     * 使用自己的 MybatisMapperRegistry
     */
    @Override
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mybatisMapperRegistry.getMapper(type, sqlSession);
    }

    /**
     * 使用自己的 MybatisMapperRegistry
     */
    @Override
    public boolean hasMapper(Class<?> type) {
        return mybatisMapperRegistry.hasMapper(type);
    }

    /**
     * 指定动态SQL生成的默认语言
     *
     * @param driver LanguageDriver
     */
    @Override
    public void setDefaultScriptingLanguage(Class<? extends LanguageDriver> driver) {
        if (driver == null) {
            //todo 替换动态SQL生成的默认语言为自己的。
            driver = MybatisXMLLanguageDriver.class;
        }
        getLanguageRegistry().setDefaultDriverClass(driver);
    }

    @Override
    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
            executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
            executor = new MybatisReuseExecutor(this, transaction);
        } else {
            executor = new MybatisSimpleExecutor(this, transaction);
        }
        if (cacheEnabled) {
            executor = new MybatisCachingExecutor(executor);
        }
        executor = (Executor) interceptorChain.pluginAll(executor);
        return executor;
    }
}

这个应该是MP之前版本的代码,我也不知道公司其他人为什么要这样,没有两个insert,只有一个

SweetInk commented 2 years ago

我复现了你上面的异常 TestMapper.java

public interface TestMapper extends BaseMapper<UserInfo> {
   @Insert("insert...")
    public void insertTest();
}

TestMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="TestMapper">
    <insert id="insertTest">
    </insert>
</mapper>
SweetInk commented 2 years ago

你的TestMaper里的Insert方法上面是不是加了Select或者Insert注解,然后你在TestMapper.xml里也写了相应的<select><insert>

jamie9762 commented 2 years ago

你的TestMaper里的Insert方法上面是不是加了Select或者Insert注解,然后你在TestMapper.xml里也写了相应的<select><insert>

还真没有.. 我把重写的文件删了就可以了

SweetInk commented 2 years ago

你的TestMaper里的Insert方法上面是不是加了Select或者Insert注解,然后你在TestMapper.xml里也写了相应的<select><insert>

还真没有.. 我把重写的文件删了就可以了

那就不明白了,问题解决了就好。