学习笔记:一个MySQL实例有多个Activiti数据库问题

使用SpringBoot + activiti6 搭建审批流项目,数据库使用的是MySQL.且我的数据库下存在多个activiti相关的数据库 schema.

org.activiti

activiti-spring-boot-starter-basic

6.0.0

配置文件

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/activiti6?useUnicode=utf8&serverTimezone=Asia/Shanghai

spring.datasource.username=root

spring.datasource.password=123456

spring.activiti.check-process-definitions=false

spring.activiti.database-schema-update=true

因为我的数据库下已经存在了一个activiti7的数据库,所以我这次又新建了一个activiti6的数据库,然后在启动的时候没有自动创建表,而是直接进行了activiti 表的查询,并报了如下的错误

org.apache.ibatis.exceptions.PersistenceException:

### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Table 'activiti6.act_ge_property' doesn't exist

### The error may exist in org/activiti/db/mapping/entity/Property.xml

### The error may involve org.activiti.engine.impl.persistence.entity.PropertyEntityImpl.selectProperty-Inline

### The error occurred while setting parameters

### SQL: select * from ACT_GE_PROPERTY where NAME_ = ?

### Cause: java.sql.SQLSyntaxErrorException: Table 'activiti6.act_ge_property' doesn't exist

然后我就开始跟断点看源码查找问题,发现它走到了如下这段代码 org.activiti.engine.impl.db.DbSqlSession (中间代码省略了一部分)

public String dbSchemaUpdate() {

String feedback = null;

boolean isUpgradeNeeded = false;

int matchingVersionIndex = -1;

if (isEngineTablePresent()) {

PropertyEntity dbVersionProperty = selectById(PropertyEntity.class, "schema.version");

....

}else {

dbSchemaCreateEngine();

}

按预想建的是空白数据库,应该要走else的逻辑,怎么会进到if里面呢,我又继续跟了 isEngineTablePresent 这个方法,很简短,就是看数据库里面表是否存在

public boolean isEngineTablePresent() {

return isTablePresent("ACT_RU_EXECUTION");

}

继续看 isTablePresent 方法,问题就出在下面这段代码上了,这个tables返回有内容,导致tables.next()为true

try {

tables = databaseMetaData.getTables(catalog, schema, tableName, JDBC_METADATA_TABLE_TYPES);

return tables.next();

} finally {

try {

tables.close();

} catch (Exception e) {

log.error("Error closing meta data tables", e);

}

}

继续看, DatabaseMetaData 是一个接口,断点进到了下面 com.zaxxer.hikari.pool.HikariProxyDatabaseMetaData#getTables ,接着调用父类的 com.zaxxer.hikari.pool.ProxyDatabaseMetaData#getTables 方法.

public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {

ResultSet resultSet = this.delegate.getTables(catalog, schemaPattern, tableNamePattern, types);

Statement statement = resultSet.getStatement();

if (statement != null) {

statement = ProxyFactory.getProxyStatement(this.connection, statement);

}

return ProxyFactory.getProxyResultSet(this.connection, (ProxyStatement)statement, resultSet);

}

this.delegate.getTables(catalog, schemaPattern, tableNamePattern, types); 这段代码进到了 com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema 这个类中.

@Override

public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {

String db = getDatabase(catalog, schemaPattern);

db = this.pedantic ? db : StringUtils.unQuoteIdentifier(db, this.quotedId);

...

}

继续跟 getDatabase() 方法.该方法实现在父类 com.mysql.cj.jdbc.DatabaseMetaData 中

protected String getDatabase(String catalog, String schema) {

if (this.databaseTerm.getValue() == DatabaseTerm.SCHEMA) {

return schema == null && this.nullDatabaseMeansCurrent.getValue() ? this.database : schema;

}

return catalog == null && this.nullDatabaseMeansCurrent.getValue() ? this.database : catalog;

}

这个时候就看到了schema和catelog的都是null,然后继续跟下去的话sql就变成了如下

SELECT TABLE_SCHEMA AS TABLE_CAT, NULL AS TABLE_SCHEM, TABLE_NAME, CASE WHEN TABLE_TYPE='BASE TABLE' THEN CASE WHEN TABLE_SCHEMA = 'mysql' OR TABLE_SCHEMA = 'performance_schema' THEN 'SYSTEM TABLE' ELSE 'TABLE' END WHEN TABLE_TYPE='TEMPORARY' THEN 'LOCAL_TEMPORARY' ELSE TABLE_TYPE END AS TABLE_TYPE, TABLE_COMMENT AS REMARKS, NULL AS TYPE_CAT, NULL AS TYPE_SCHEM, NULL AS TYPE_NAME, NULL AS SELF_REFERENCING_COL_NAME, NULL AS REF_GENERATION FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'ACT_RU_EXECUTION' HAVING TABLE_TYPE IN ('TABLE',null,null,null,null) ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME

根据这个sql执行的结果可以看到我的数据库中是存在数据的

学习笔记:一个MySQL实例有多个Activiti数据库问题

然后就可开始看为什么catalog为null呢,然后就继续看 nullDatabaseMeansCurrent 这个属性(其实跟到getDatabase()方法的时候已经进到了mysql-connector-java的类中了).

这个属性在 com.mysql.cj.jdbc.DatabaseMetaData 的定义为

protected RuntimeProperty nullDatabaseMeansCurrent;

看该类的构造方法可以看到

protected DatabaseMetaData(JdbcConnection connToSet, String databaseToSet, ResultSetFactory resultSetFactory) {

this.conn = connToSet;

this.session = (NativeSession) connToSet.getSession();

this.database = databaseToSet;

this.resultSetFactory = resultSetFactory;

this.exceptionInterceptor = this.conn.getExceptionInterceptor();

this.databaseTerm = this.conn.getPropertySet().getEnumProperty(PropertyKey.databaseTerm);

this.nullDatabaseMeansCurrent = this.conn.getPropertySet().getBooleanProperty(PropertyKey.nullDatabaseMeansCurrent);

this.pedantic = this.conn.getPropertySet().getBooleanProperty(PropertyKey.pedantic).getValue();

this.tinyInt1isBit = this.conn.getPropertySet().getBooleanProperty(PropertyKey.tinyInt1isBit).getValue();

this.transformedBitIsBoolean = this.conn.getPropertySet().getBooleanProperty(PropertyKey.transformedBitIsBoolean).getValue();

this.useHostsInPrivileges = this.conn.getPropertySet().getBooleanProperty(PropertyKey.useHostsInPrivileges).getValue();

this.quotedId = this.session.getIdentifierQuoteString();

}

在 com.mysql.cj.conf.PropertyKey 类中可以看到

nullDatabaseMeansCurrent("nullDatabaseMeansCurrent", "nullCatalogMeansCurrent", true), //

然后跟到 com.mysql.cj.conf.DefaultPropertySet

public DefaultPropertySet() {

for (PropertyDefinition> pdef : PropertyDefinitions.PROPERTY_KEY_TO_PROPERTY_DEFINITION.values()) {

addProperty(pdef.createRuntimeProperty());

}

}

可以看到 PropertyDefinitions.PROPERTY_KEY_TO_PROPERTY_DEFINITION

跟到 com.mysql.cj.conf.PropertyDefinitions 类中,果然发现了 nullDatabaseMeansCurrent 的定义.

new BooleanPropertyDefinition(PropertyKey.nullDatabaseMeansCurrent, DEFAULT_VALUE_FALSE, RUNTIME_MODIFIABLE,

Messages.getString("ConnectionProperties.nullCatalogMeansCurrent"), "3.1.8", CATEGORY_METADATA, Integer.MIN_VALUE),

可以看到他的默认值为false.

然后我们在配置文件的数据库链接上加上 &nullCatalogMeansCurrent=true ,然后重新执行程序.发现数据库表插入正常.问题解决.

最后的配置文件:

spring.datasource.url=jdbc:mysql://localhost:3306/activiti6?useUnicode=utf8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true

spring.datasource.username=root

spring.datasource.password=123456

spring.activiti.check-process-definitions=false

spring.activiti.database-schema-update=true

activiti7关联mysql_学习笔记:一个MySQL实例有多个Activiti数据库问题相关推荐

  1. mysql数据库服务器实例_服务器上运行一个mysql实例里有多个数据库呢?还是多MYSQL实例?...

    二个以上的网2113站共同使用一个MYSQL数据库,这种方式5261可以是的,在建站实践中可以执4102行,而且很多站长也1653是采用这种方式建过站.我们只需要保障每个网站的"MYSQL数 ...

  2. 命名空间不能直接包含字段或方法之类的成员是什么意思_Python 学习笔记之类与实例...

    Python 学习笔记之类与实例 一.定义 1.1.定义 类 (class) 封装一组相关数据,使之成为一个整体,并使用一种方法持续展示和维护. 这有点像把零件组装成整车提供给用户,无须了解汽车的内部 ...

  3. HALCON 21.11:深度学习笔记---对象检测, 实例分割(11)

    HALCON 21.11:深度学习笔记---对象检测, 实例分割(11) HALCON 21.11.0.0中,实现了深度学习方法. 本章介绍了如何使用基于深度学习的对象检测. 通过对象检测,我们希望在 ...

  4. Unity 2D 学习笔记:游戏实例Sunnyland

    Unity 2D 学习笔记:游戏实例Sunnyland 01安装软件&导入素材 02编辑素材&Tilemap 03图层layer&角色建立 04角色移动 05角色方向& ...

  5. 架构mysql_MySQL学习笔记之MySQL架构

    MySQL 最重要.最与众不同的特性是它的存储引擎架构,这种架构的设计将查询处理及其他系统任务和数据的存储/提取相分离.这种处理和存储分离的设计可以在使用时根据性能.特性,以及其他需求来选择数据存储的 ...

  6. MySQL学习笔记 | 04 - MySQL数据库基本操作(增加、修改、删除、查看)

    MySQL学习笔记 | 01-为什么要使用数据库 MySQL学习笔记 | 02 - MySQL在Windows下的安装.配置.服务启动/停止.用户登录.查看版本号 MySQL学习笔记 | 03 - M ...

  7. Quartz.NET 2.0 学习笔记(5) :实例创建Windows服务实现任务调度 Quartz.NET 项目地址 http://quartznet.sourceforge.net/ Quar

    Quartz.NET 2.0 学习笔记(5) :实例创建Windows服务实现任务调度 Quartz.NET 项目地址 http://quartznet.sourceforge.net/ Quartz ...

  8. 学习笔记--一个自管理(组织)的多目标进化算法(SMEA)

    学习笔记–一个自管理(组织)的多目标进化算法(SMEA) 摘要:在温和条件下,一个连续m维目标的优化问题的帕累托前沿(解集)可以形成一个(m-1)维的分段连续流形.基于这个性质,这篇文章提出了一个自管 ...

  9. oracle scn 重置,学习笔记:Oracle SCN详解 SCN与Oracle数据库恢复的关系

    天萃荷净 分享一篇关于Oracle SCN的详解,介绍SCN与Oracle数据库恢复的关系和SCN在数据库中的作用 一.为什么需要System checkpoint SCN号与Datafile Che ...

最新文章

  1. Unity学习笔记 - Assets, Objects and Serialization
  2. 老鸟运维该何去何从?
  3. UGUI_UGUI组件属性
  4. 用Blazor技术封装G2Plot实现Charts组件
  5. 【渝粤教育】电大中专幼儿园组织与管理 (10)作业 题库
  6. C语言输出最后一个空格去掉,新人提问:如何将输出时每行最后一个空格删除...
  7. linux可配置哪些服务,linux操作系统下服务配置
  8. Spring MVC学习总结(11)——Spring MVC集成Swagger跨域问题
  9. php大文件读,PHP读取大文件
  10. 在ubuntu下配置C和C++的编译环境
  11. 一人饮酒醉用计算机版,玩家自制游戏版《一人饮酒醉》,歪唱喊麦笑翻全场
  12. 王春亮推拿学堂:如何成为一名高级调理师
  13. ECCV2022论文列表(中英对照)
  14. FlashFXP命令行
  15. python成功安装cartopy之后,调用crs时却出现错误,如何解决
  16. 好用的识别植物的软件app合集分享,快码住了
  17. 压力引起焦虑竟是因为免疫细胞被“压垮”
  18. Efficient Methods for Natural Language Processing: A Survey自然语言处理有效方法综述
  19. 开源许可协议 | GNU GPL
  20. 数字图像处理MATLAB学习笔记(五)

热门文章

  1. EF Code First建库 增删改查
  2. 安装Eclipse ADT插件时遇到的一些问题,错误
  3. kibana界面汉化
  4. MongoDB数据库常见问题
  5. 1 Linux SSH安全加固
  6. Linux(Ubuntu)如何处理新添加的硬盘
  7. 2022-01-12总结 CSS开篇
  8. mysql安装服务和安装中常见问题install/Remove of the Service Denied与net start mysql服务启动失败解决方法
  9. 关于如何查看 EntityValidationErrors 详细信息的解决方法
  10. java向mysql插入数据乱码问题解决