问题描述
在配置完Springboot的开发环境以后,启动的时候遇到了这个问题,数据库版本为mysql 5.7,Flowable版本为6.4.0,详细报错如下:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'flowController': Unsatisfied dependency expressed through field 'flowService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'flowServiceImpl': Unsatisfied dependency expressed through field 'repositoryService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'repositoryServiceBean' defined in class path resource [org/flowable/spring/boot/ProcessEngineServicesAutoConfiguration.class]: Unsatisfied dependency expressed through method 'repositoryServiceBean' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'processEngine' defined in class path resource [org/flowable/spring/boot/ProcessEngineServicesAutoConfiguration$AlreadyInitializedAppEngineConfiguration.class]: Unsatisfied dependency expressed through method 'processEngine' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flowableAppEngine': FactoryBean threw exception on object creation; nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Table 'flowstudy.act_ge_property' doesn't exist
### The error may exist in org/flowable/db/mapping/entity/Property.xml
### The error may involve org.flowable.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 'flowstudy.act_ge_property' doesn't exist
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1341) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at com.hyj.main.App.main(App.java:22) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.0.5.RELEASE.jar:2.0.5.RELEASE]
问题定位
- 看提示显示表不存在说明数据库中没有该表,此时查看的确没有,但是Flowable启动的时候应该会自动创建表的,说明表创建的逻辑判断发生问题
- 查看代码发现判断主要函数为:
isEngineTablePresent
代码位于类 ProcessDbSchemaManager中,核心判断存在如下:
public void schemaCreate() {
this.getCommonSchemaManager().schemaCreate();
this.getIdentityLinkSchemaManager().schemaCreate();
this.getTaskSchemaManager().schemaCreate();
this.getVariableSchemaManager().schemaCreate();
this.getJobSchemaManager().schemaCreate();
//使用这个函数判断是否要创建引擎
if (this.isEngineTablePresent()) {
String dbVersion = this.getDbVersion();
if (!"6.4.0.0".equals(dbVersion)) {
throw new FlowableWrongDbException("6.4.0.0", dbVersion);
}
} else {
this.dbSchemaCreateEngine();
}
if (CommandContextUtil.getDbSqlSession().getDbSqlSessionFactory().isDbHistoryUsed()) {
this.dbSchemaCreateHistory();
}
}
更新的时候,设置databaseSchemaUpdate=true的时候,走update,可以看到如下代码也是使用isEngineTablePresent来判断是否存在
public String schemaUpdate() {
PropertyEntity dbVersionProperty = null;
String dbVersion = null;
String feedback = null;
boolean isUpgradeNeeded = false;
int matchingVersionIndex = -1;
int version6120Index = FlowableVersions.getFlowableVersionIndexForDbVersion("6.1.2.0");
DbSqlSession dbSqlSession = CommandContextUtil.getDbSqlSession();
boolean isEngineTablePresent = this.isEngineTablePresent();
if (isEngineTablePresent) {
dbVersionProperty = (PropertyEntity)dbSqlSession.selectById(PropertyEntityImpl.class, "schema.version");
dbVersion = dbVersionProperty.getValue();
matchingVersionIndex = FlowableVersions.getFlowableVersionIndexForDbVersion(dbVersion);
isUpgradeNeeded = matchingVersionIndex != FlowableVersions.FLOWABLE_VERSIONS.size() - 1;
}
boolean isHistoryTablePresent = this.isHistoryTablePresent();
if (isUpgradeNeeded && matchingVersionIndex < version6120Index) {
this.dbSchemaUpgradeUntil6120("engine", matchingVersionIndex);
if (isHistoryTablePresent) {
this.dbSchemaUpgradeUntil6120("history", matchingVersionIndex);
}
}
this.getCommonSchemaManager().schemaUpdate();
this.getIdentityLinkSchemaManager().schemaUpdate();
this.getTaskSchemaManager().schemaUpdate();
this.getVariableSchemaManager().schemaUpdate();
this.getJobSchemaManager().schemaUpdate();
if (isUpgradeNeeded) {
dbVersionProperty.setValue("6.4.0.0");
PropertyEntity dbHistoryProperty;
if ("5.0".equals(dbVersion)) {
dbHistoryProperty = (PropertyEntity)CommandContextUtil.getPropertyEntityManager().create();
dbHistoryProperty.setName("schema.history");
dbHistoryProperty.setValue("create(5.0)");
dbSqlSession.insert(dbHistoryProperty);
} else {
dbHistoryProperty = (PropertyEntity)dbSqlSession.selectById(PropertyEntity.class, "schema.history");
}
String dbHistoryValue = "upgrade(" + dbVersion + "->" + "6.4.0.0" + ")";
dbHistoryProperty.setValue(dbHistoryValue);
if (version6120Index > matchingVersionIndex) {
this.dbSchemaUpgrade("engine", version6120Index);
} else {
this.dbSchemaUpgrade("engine", matchingVersionIndex);
}
feedback = "upgraded Flowable from " + dbVersion + " to " + "6.4.0.0";
} else if (!isEngineTablePresent) {
this.dbSchemaCreateEngine();
}
if (isHistoryTablePresent) {
if (isUpgradeNeeded) {
if (version6120Index > matchingVersionIndex) {
this.dbSchemaUpgrade("history", version6120Index);
} else {
this.dbSchemaUpgrade("history", matchingVersionIndex);
}
}
} else if (dbSqlSession.getDbSqlSessionFactory().isDbHistoryUsed()) {
this.dbSchemaCreateHistory();
}
return feedback;
}
- isEngineTablePresent代码实现如下:
可以看到使用的是表ACT_RU_EXECUTION是否存在来判断的
public boolean isEngineTablePresent() {
return this.isTablePresent("ACT_RU_EXECUTION");
}
- 进一步跟踪看到isTablePresent的实现如下:
public boolean isTablePresent(String tableName) {
DbSqlSession dbSqlSession = this.getDbSqlSession();
DbSqlSessionFactory dbSqlSessionFactory = dbSqlSession.getDbSqlSessionFactory();
if (!dbSqlSession.getDbSqlSessionFactory().isTablePrefixIsSchema()) {
tableName = this.prependDatabaseTablePrefix(tableName);
}
Connection connection = null;
try {
connection = dbSqlSession.getSqlSession().getConnection();
DatabaseMetaData databaseMetaData = connection.getMetaData();
ResultSet tables = null;
String catalog = dbSqlSession.getConnectionMetadataDefaultCatalog();
if (dbSqlSessionFactory.getDatabaseCatalog() != null && dbSqlSessionFactory.getDatabaseCatalog().length() > 0) {
catalog = dbSqlSessionFactory.getDatabaseCatalog();
}
String schema = dbSqlSession.getConnectionMetadataDefaultSchema();
if (dbSqlSessionFactory.getDatabaseSchema() != null && dbSqlSessionFactory.getDatabaseSchema().length() > 0) {
schema = dbSqlSessionFactory.getDatabaseSchema();
} else if (dbSqlSessionFactory.isTablePrefixIsSchema() && StringUtils.isNotEmpty(dbSqlSessionFactory.getDatabaseTablePrefix())) {
schema = dbSqlSessionFactory.getDatabaseTablePrefix();
if (StringUtils.isNotEmpty(schema) && schema.endsWith(".")) {
schema = schema.substring(0, schema.length() - 1);
}
}
String databaseType = dbSqlSessionFactory.getDatabaseType();
if ("postgres".equals(databaseType)) {
tableName = tableName.toLowerCase();
}
if (schema != null && "oracle".equals(databaseType)) {
schema = schema.toUpperCase();
}
if (catalog != null && catalog.length() == 0) {
catalog = null;
}
boolean var10;
try {
//查询元数据中的表,根据schema和tablename查看
tables = databaseMetaData.getTables(catalog, schema, tableName, JDBC_METADATA_TABLE_TYPES);
var10 = tables.next();
} finally {
try {
if (tables != null) {
tables.close();
}
} catch (Exception var18) {
LOGGER.error("Error closing meta data tables", var18);
}
}
return var10;
} catch (Exception var20) {
throw new FlowableException("couldn't check if tables are already present using metadata: " + var20.getMessage(), var20);
}
}
- 我们启动程序跟踪进入,查看使用getTables读取表,如下图所示:
-因为机器上以前其他的mysql数据库中部署过Flowable的表,所以当schema为空的时候搜索mysql的元数据的时候搜索到了历史用的表,但是不在该数据库中,所以程序以为表已经有了,但是其实还是历史的表,到此我们基本上找到原因了。 - 我们使用的驱动为8.0的驱动,8.0版本驱动将参数 nullCatalogMeansCurrent 的默认值由true改为了false,如果你使用DatabaseMetaData.getTables获取所有的表信息。
解决方案一
把正常的数据库的表导出为sql,手动创建表。
解决方案二(推荐)
mysql的连接字符串中添加上nullCatalogMeansCurrent=true,将schema默认设置为当前连接的schema。
验证结果
今天的文章Flowable深入浅出-6 Flowable-Modeler详述之常见问题Table act_ge_property doesn‘t exist分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/7519.html