2019-10-30 21:50:17.342 ERROR 18364 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cn.superdesk.libs.springboot.starter.mybatis.SuperdeskMybatisConfiguration': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Mapped Statements collection already contains value for cn.superdesk.app.core.dao.mapper.AppUserFloorEntityMapper.selectByPrimaryKey
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1699)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:137)
at cn.superdesk.app.transfer.canal.instance.supercloud.ApplicationStarter.main(ApplicationStarter.java:48)
Caused by: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for cn.superdesk.app.core.dao.mapper.AppUserFloorEntityMapper.selectByPrimaryKey
at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:872)
at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:844)
at org.apache.ibatis.session.Configuration.addMappedStatement(Configuration.java:668)
at cn.superdesk.libs.mybatis.crud.builder.GetByPrimaryKeyBuilder.build(GetByPrimaryKeyBuilder.java:53)
at cn.superdesk.libs.mybatis.crud.GeneralSqlGenerator.generate(GeneralSqlGenerator.java:45)
at cn.superdesk.libs.mybatis.spring.SuperdeskMybatisRegistry.register(SuperdeskMybatisRegistry.java:25)
at cn.superdesk.libs.springboot.starter.mybatis.SuperdeskMybatisConfiguration.afterPropertiesSet(SuperdeskMybatisConfiguration.java:42)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695)
... 15 common frames omitted
先去看几个文章
springboot2.0.6(附) 解析META-INF/spring.factories通过系统加载类获取对应的 class 的全限定名称 - 小亮89的个人空间 - OSCHINA 解析META-INF/spring.factories通过系统加载类获取对应的 class 的全限定名称 - 小亮89的个人空间 - OSCHINA")
Spring Boot的扩展机制之Spring Factories - 程序员伊成 - CSDN博客
springboot2.0自动注入文件spring.factories如何加载详解 - 简书
/mnt1t/JAVA_HOME/superdesk-libs/superdesk-libs-springboot-starter/src/main/resources/META-INF/spring.factories/mnt1t/JAVA_HOME/superdesk-libs/superdesk-libs-springboot-starter/src/main/resources/META-INF/spring.provides
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.superdesk.libs.springboot.starter.mybatis.SuperdeskMybatisConfiguration,\
cn.superdesk.libs.springboot.starter.cache.DelegateCacheConfiguration
package cn.superdesk.libs.springboot.starter.mybatis;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternUtils;
import cn.superdesk.libs.mybatis.MybatisConfigs;
import cn.superdesk.libs.mybatis.datasource.MutiRouteDataSource;
import cn.superdesk.libs.mybatis.parser.MybatisMapperParser;
import cn.superdesk.libs.mybatis.spring.SuperdeskMybatisRegistry;
@Configuration
@EnableConfigurationProperties(MybatisPluginProperties.class)
@ConditionalOnClass(MutiRouteDataSource.class)
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class SuperdeskMybatisConfiguration implements InitializingBean {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Autowired
private MybatisPluginProperties properties;
@Value("${mybatis.mapper-locations}")
private String mapperLocations;
@Override
public void afterPropertiesSet() throws Exception {
Resource[] resources = ResourcePatternUtils.getResourcePatternResolver(new DefaultResourceLoader()).getResources(mapperLocations);
String group = "default";
MybatisMapperParser.addMapperLocations(group,resources);
MybatisConfigs.addProperties(group, properties.getProperties());
SuperdeskMybatisRegistry.register(group,sqlSessionFactory.getConfiguration());
}
}
package cn.superdesk.libs.springboot.starter.mybatis;
import java.util.Properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import cn.superdesk.libs.mybatis.MybatisConfigs;
/**
* @author superdesk
* @description
* @date 2016年12月31日
*/
@ConfigurationProperties(prefix = "superdesk.mybatis")
public class MybatisPluginProperties {
private Properties properties = new Properties();
public void setCacheEnabled(boolean cacheEnabled) {
properties.setProperty(MybatisConfigs.CACHE_ENABLED, String.valueOf(cacheEnabled));
}
public void setRwRouteEnabled(boolean rwRouteEnabled) {
properties.setProperty(MybatisConfigs.RW_ROUTE_ENABLED, String.valueOf(rwRouteEnabled));
}
public void setPaginationEnabled(boolean paginationEnabled) {
properties.setProperty(MybatisConfigs.PAGINATION_ENABLED, String.valueOf(paginationEnabled));
}
public void setDbType(String dbType) {
properties.setProperty(MybatisConfigs.DB_TYPE, dbType);
}
public void setCrudDriver(String crudDriver) {
properties.setProperty(MybatisConfigs.CRUD_DRIVER, crudDriver);
}
public void setNullValueCache(boolean nullValueCache) {
properties.setProperty(MybatisConfigs.CACHE_NULL_VALUE, String.valueOf(nullValueCache));
}
public void setCacheExpireSeconds(long cacheExpireSeconds) {
properties.setProperty(MybatisConfigs.CACHE_EXPIRE_SECONDS, String.valueOf(cacheExpireSeconds));
}
public void setDynamicExpire(boolean dynamicExpire) {
properties.setProperty(MybatisConfigs.CACHE_DYNAMIC_EXPIRE, String.valueOf(dynamicExpire));
}
public void setInterceptorHandlerClass(String interceptorHandlerClass) {
properties.setProperty(MybatisConfigs.INTERCEPTOR_HANDLERCLASS, interceptorHandlerClass);
}
public Properties getProperties() {
return properties;
}
}
看到这, 关键点在这, 得加入这个
# mybatis
superdesk.mybatis.crudDriver=mapper3
#superdesk.mybatis.dbType=Mysql
superdesk.mybatis.cacheEnabled=false
superdesk.mybatis.dynamicExpire=false
superdesk.mybatis.cacheExpireSeconds=3600
#superdesk.mybatis.rwRouteEnabled=false
superdesk.mybatis.paginationEnabled=true
问题来了
其实 这个mybatis mapper xml 很有可能加载了两次
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.2.4</version>
</dependency>
类 spi Service Provider Interface
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.superdesk.libs.springboot.starter.mybatis.SuperdeskMybatisConfiguration,\
cn.superdesk.libs.springboot.starter.cache.DelegateCacheConfiguration
->
SuperdeskMybatisConfiguration
@Configuration
@EnableConfigurationProperties(MybatisPluginProperties.class)
@ConditionalOnClass(MutiRouteDataSource.class)
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class SuperdeskMybatisConfiguration implements InitializingBean {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Autowired
private MybatisPluginProperties properties;
@Value("${mybatis.mapper-locations}")
private String mapperLocations;
@Override
public void afterPropertiesSet() throws Exception {
Resource[] resources = ResourcePatternUtils.getResourcePatternResolver(new DefaultResourceLoader()).getResources(mapperLocations);
String group = "default";
MybatisMapperParser.addMapperLocations(group,resources);
MybatisConfigs.addProperties(group, properties.getProperties());
SuperdeskMybatisRegistry.register(group,sqlSessionFactory.getConfiguration());
}
}
作用地方
@EnableConfigurationProperties(MybatisPluginProperties.class)
@ConditionalOnClass(MutiRouteDataSource.class)
@AutoConfigureAfter(MybatisAutoConfiguration.class)
@Override
public void afterPropertiesSet() throws Exception {
Resource[] resources = ResourcePatternUtils.getResourcePatternResolver(new DefaultResourceLoader()).getResources(mapperLocations);
String group = "default";
// MARK 001 加到一个新的 group 上 再解决转换
MybatisMapperParser.addMapperLocations(group,resources);
MybatisConfigs.addProperties(group, properties.getProperties());
// MARK 002 再注册了一次
SuperdeskMybatisRegistry.register(group,sqlSessionFactory.getConfiguration());
}
public class SuperdeskMybatisRegistry {
public static void register(String group, Configuration configuration) throws Exception {
if ("default".equals(MybatisConfigs.getCrudDriver(group))) {
new GeneralSqlGenerator(group, configuration).generate();
} else if ("mapper3".equals(MybatisConfigs.getCrudDriver(group))) {
Class<?> helperClazz = Class.forName("tk.mybatis.mapper.mapperhelper.MapperHelper");
Object helper = helperClazz.newInstance();
Class<?> configClazz = Class.forName("tk.mybatis.mapper.entity.Config");
Object config = configClazz.newInstance();
Method method = configClazz.getDeclaredMethod("setNotEmpty", boolean.class);
method.invoke(config, false);
method = helperClazz.getDeclaredMethod("setConfig", configClazz);
method.invoke(helper, config);
method = helperClazz.getDeclaredMethod("registerMapper", Class.class);
List<EntityInfo> entityInfos = MybatisMapperParser.getEntityInfos(group);
for (EntityInfo entityInfo : entityInfos) {
method.invoke(helper, entityInfo.getMapperClass());
}
method = helperClazz.getDeclaredMethod("processConfiguration", Configuration.class);
method.invoke(helper, configuration);
} else {
new GeneralSqlGenerator(group, configuration).generate();
}
//注册拦截器
String[] hanlderNames = MybatisConfigs.getHanlderNames(group);
if (hanlderNames.length > 0) {
SuperdeskMybatisInterceptor interceptor = new SuperdeskMybatisInterceptor(group, hanlderNames);
configuration.addInterceptor(interceptor);
interceptor.afterRegister();
}
}
}
关键是这个mapper3 不走 default 不走 else , 如果没配置就会走 else 去生成, 就会报错了
/**
* @author superdesk
* @description
* @date 2016年2月2日
*/
public class GeneralSqlGenerator {
private static final Logger log = LoggerFactory.getLogger(GeneralSqlGenerator.class);
public static DefaultCrudMethodDefine methodDefines = new DefaultCrudMethodDefine();
private LanguageDriver languageDriver;
private Configuration configuration;
private String group;
public GeneralSqlGenerator(String group, Configuration configuration) {
this.group = group;
this.configuration = configuration;
this.languageDriver = configuration.getDefaultScriptingLanguageInstance();
}
public void generate() {
if (languageDriver == null) languageDriver = configuration.getDefaultScriptingLanguageInstance();
List<EntityInfo> entityInfos = MybatisMapperParser.getEntityInfos(group);
for (EntityInfo entity : entityInfos) {
//TODO 排除生成
GetByPrimaryKeyBuilder.build(configuration, languageDriver, entity);
InsertBuilder.build(configuration, languageDriver, entity);
UpdateBuilder.build(configuration, languageDriver, entity);
DeleteBuilder.build(configuration, languageDriver, entity);
BatchInsertBuilder.build(configuration, languageDriver, entity);
SelectAllBuilder.build(configuration, languageDriver, entity);
log.info(" >> generate autoCrud for:[{}] finish", entity.getEntityClass().getName());
}
}
}
GetByPrimaryKeyBuilder.build(configuration, languageDriver, entity);
这个再生成动态 sql 的就会报错了
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论