网站网页链接,青岛工程建设管理信息网官方网站,个人网站开发视频,网站底部版权html代码文章目录 适配相关问题无法从数据库产品名称“DM DBMS”中推断数据库类型分析解决 构建ibatis SqlSessionFactory时出错#xff1a;inStream参数为null分析解决 liquibase相关问题问题一#xff1a;不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访… 文章目录 适配相关问题无法从数据库产品名称“DM DBMS”中推断数据库类型分析解决 构建ibatis SqlSessionFactory时出错inStream参数为null分析解决 liquibase相关问题问题一不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访问表达式[CURRENT_SCHEMA]分析解决 问题二找不到 setRemarksReporting 方法解决 问题三存储过程问题问题Cannot read from DBMS_UTILITY.DB_VERSION: 无效的方法名[DB_VERSION]分析解决 问题四: 更新事件注册表引擎表时出错、初始化事件注册表数据模型时出错解决 问题五验证事件注册表引擎架构时出错解决 数据库版本问题version mismatch: library version is 7.0.1.1, db version is 7.0.0.0解决 启动流程相关问题解决 服务启动成功日志 网上flowable7新版本适配文档较少以下使用部署flowable7源码方式说明相关适配问题。
适配相关问题
无法从数据库产品名称“DM DBMS”中推断数据库类型 分析
先查看较为完整的堆栈信息调用流程看一下怎么个事
实例化bean 类型为class com.xxxx.workflow.service.impl.ProcessServiceImp
通过反射实例化后填充属性依赖注入
主要看注入flowable内置的Service 解析taskService字段
解析依赖关系 根据beanNametaskServiceBean和typeorg.flowable.engine.TaskService得到要注入的实例 给taskService属性赋值 以上执行完就给taskSerive字段属性赋值了报错是在执行 org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate方法时也就是实例化taskService的时候 实例化taskService 从bena定义信息中可以看出有工厂方法 返回的是taskService 所以通过工厂方法实例化 得到候选实例的参数 解析注入参数processEngine 根据beanNameprocessEngine和typeorg.flowable.engine.ProcessEngine得到要注入的实例 实例化processEngine 从bean定义信息中可以看出是通过 ProcessEngineFactoryBean 定制化创建的ProcessEngine在ProcessEngineFactoryBean的getOject方法中会构建流程引擎
public class ProcessEngineFactoryBean implements FactoryBeanProcessEngine, DisposableBean, ApplicationContextAware {protected ProcessEngineConfigurationImpl processEngineConfiguration;protected ApplicationContext applicationContext;protected ProcessEngine processEngine;Overridepublic void destroy() throws Exception {if (processEngine ! null) {processEngine.close();}}Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext applicationContext;}Overridepublic ProcessEngine getObject() throws Exception {configureExternallyManagedTransactions();if (processEngineConfiguration.getBeans() null) {processEngineConfiguration.setBeans(new SpringBeanFactoryProxyMap(applicationContext));}// 构建流程引擎this.processEngine processEngineConfiguration.buildProcessEngine();return this.processEngine;}protected void configureExternallyManagedTransactions() {if (processEngineConfiguration instanceof SpringProcessEngineConfiguration) { // remark: any config can be injected, so we cannot have SpringConfiguration as memberSpringProcessEngineConfiguration engineConfiguration (SpringProcessEngineConfiguration) processEngineConfiguration;if (engineConfiguration.getTransactionManager() ! null) {processEngineConfiguration.setTransactionsExternallyManaged(true);}}}Overridepublic ClassProcessEngine getObjectType() {return ProcessEngine.class;}Overridepublic boolean isSingleton() {return true;}public ProcessEngineConfigurationImpl getProcessEngineConfiguration() {return processEngineConfiguration;}public void setProcessEngineConfiguration(ProcessEngineConfigurationImpl processEngineConfiguration) {this.processEngineConfiguration processEngineConfiguration;}
}通过ProcessEngineFactoryBean的getOject获取processEngine实例的对象 重点在这里
org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl#buildProcessEngine 构建流程引擎
org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl#init 初始化
org.flowable.common.engine.impl.AbstractEngineConfiguration#initDataSource 初始化数据源
org.flowable.common.engine.impl.AbstractEngineConfiguration#initDatabaseType 初始化数据源类型 databaseProductName为DM DBMS
从org.flowable.common.engine.impl.AbstractEngineConfiguration#getDefaultDatabaseTypeMappings 从数据库类型映射中获取DM DBMS看看有没有没有则抛出异常 public void initDatabaseType() {Connection connection null;try {connection dataSource.getConnection();DatabaseMetaData databaseMetaData connection.getMetaData();//databaseProductName为DM DBMSString databaseProductName databaseMetaData.getDatabaseProductName(); logger.debug(database product name: {}, databaseProductName);// 如果是PostgreSQL做一下处理...if (PRODUCT_NAME_POSTGRES.equalsIgnoreCase(databaseProductName)) {try (PreparedStatement preparedStatement connection.prepareStatement(select version() as version;);ResultSet resultSet preparedStatement.executeQuery()) {String version null;if (resultSet.next()) {version resultSet.getString(version);}if (StringUtils.isNotEmpty(version) version.toLowerCase().startsWith(PRODUCT_NAME_CRDB.toLowerCase())) {databaseProductName PRODUCT_NAME_CRDB;logger.info(CockroachDB version {} detected, version);}}}//从org.flowable.common.engine.impl.AbstractEngineConfiguration#getDefaultDatabaseTypeMappings获取DM DBMS看看有没有databaseType databaseTypeMappings.getProperty(databaseProductName);if (databaseType null) {throw new FlowableException(couldnt deduct database type from database product name databaseProductName );}logger.debug(using database type: {}, databaseType);} catch (SQLException e) {throw new RuntimeException(Exception while initializing Database connection, e);} finally {try {if (connection ! null) {connection.close();}} catch (SQLException e) {logger.error(Exception while closing the Database connection, e);}}if (DATABASE_TYPE_MSSQL.equals(databaseType)) {maxNrOfStatementsInBulkInsert DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER;}}public static Properties getDefaultDatabaseTypeMappings() {Properties databaseTypeMappings new Properties();databaseTypeMappings.setProperty(H2, DATABASE_TYPE_H2);databaseTypeMappings.setProperty(HSQL Database Engine, DATABASE_TYPE_HSQL);databaseTypeMappings.setProperty(MySQL, DATABASE_TYPE_MYSQL);databaseTypeMappings.setProperty(MariaDB, DATABASE_TYPE_MYSQL);databaseTypeMappings.setProperty(Oracle, DATABASE_TYPE_ORACLE);databaseTypeMappings.setProperty(PRODUCT_NAME_POSTGRES, DATABASE_TYPE_POSTGRES);databaseTypeMappings.setProperty(Microsoft SQL Server, DATABASE_TYPE_MSSQL);databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/NT, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/NT64, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2 UDP, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/LINUX, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/LINUX390, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/LINUXX8664, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/LINUXZ64, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/LINUXPPC64, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/LINUXPPC64LE, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/400 SQL, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/6000, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2 UDB iSeries, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/AIX64, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/HPUX, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/HP64, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/SUN, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/SUN64, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/PTX, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2/2, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(DB2 UDB AS400, DATABASE_TYPE_DB2);databaseTypeMappings.setProperty(PRODUCT_NAME_CRDB, DATABASE_TYPE_COCKROACHDB);return databaseTypeMappings;}解决
添加达梦数据库类型映射
org.flowable.common.engine.impl.AbstractEngineConfiguration 构建ibatis SqlSessionFactory时出错inStream参数为null 分析
定位
上面流程初始化了数据源数据源类型等
在org.flowable.common.engine.impl.AbstractEngineConfiguration#initSqlSessionFactory初始化SqlSessionFactory会根据数据源类型读取配置org/flowable/common/db/properties/dm.properties没有dm的配置mybatis分页相关配置报InputStream为null public void initSqlSessionFactory() {if (sqlSessionFactory null) {InputStream inputStream null;try {// 读取org/flowable/db/mapping/mappings.xmlinputStream getMyBatisXmlConfigurationStream();Environment environment new Environment(default, transactionFactory, dataSource);Reader reader new InputStreamReader(inputStream);Properties properties new Properties();properties.put(prefix, databaseTablePrefix);String wildcardEscapeClause ;if ((databaseWildcardEscapeCharacter ! null) (databaseWildcardEscapeCharacter.length() ! 0)) {wildcardEscapeClause escape databaseWildcardEscapeCharacter ;}properties.put(wildcardEscapeClause, wildcardEscapeClause);// set default propertiesproperties.put(limitBefore, );properties.put(limitAfter, );properties.put(limitBetween, );properties.put(limitBeforeNativeQuery, );properties.put(limitAfterNativeQuery, );properties.put(blobType, BLOB);properties.put(boolValue, TRUE);if (databaseType ! null) {// 读取org/flowable/common/db/properties/dm.properties 设置propertiesproperties.load(getResourceAsStream(pathToEngineDbProperties()));}// Configuration configuration initMybatisConfiguration(environment, reader, properties);sqlSessionFactory new DefaultSqlSessionFactory(configuration);} catch (Exception e) {throw new FlowableException(Error while building ibatis SqlSessionFactory: e.getMessage(), e);} finally {IoUtil.closeSilently(inputStream);}} else {applyCustomMybatisCustomizations(sqlSessionFactory.getConfiguration());}}解决
添加dm.properties 参考oracle limitBeforeselect RES.* from ( select RES.*, rownum as rnum from (
limitAfter ) RES where ROWNUM #{lastRow} ) RES where rnum #{firstRow}
boolValue1liquibase相关问题
liquibase版本为4.20.0 问题一不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访问表达式[CURRENT_SCHEMA]
liquibase.exception.DatabaseException: Error executing SQL call current_schema: 第1 行附近出现错误:
无法解析的成员访问表达式[CURRENT_SCHEMA] 分析
定位
org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl#buildProcessEngine
org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl#init
org.flowable.common.engine.impl.AbstractEngineConfiguration#configuratorsAfterInit
org.flowable.eventregistry.impl.EventRegistryEngineConfiguration#buildEventRegistryEngine
org.flowable.eventregistry.impl.EventRegistryEngineConfiguration#init
org.flowable.eventregistry.impl.EventRegistryEngineImpl 实例化
org.flowable.eventregistry.impl.db.EventDbSchemaManager#initSchema
org.flowable.common.engine.impl.db.LiquibaseBasedSchemaManager#createLiquibaseInstance 创建Liquibase实例 protected Liquibase createLiquibaseInstance(LiquibaseDatabaseConfiguration databaseConfiguration) throws SQLException {Connection jdbcConnection null;boolean closeConnection false;try {CommandContext commandContext Context.getCommandContext();if (commandContext null) {jdbcConnection databaseConfiguration.getDataSource().getConnection();closeConnection true;} else {jdbcConnection commandContext.getSession(DbSqlSession.class).getSqlSession().getConnection();}if (!jdbcConnection.getAutoCommit()) {jdbcConnection.commit();}// 创建jdbc连接DatabaseConnection connection new JdbcConnection(jdbcConnection);// 创建数据库实例Database database DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);// 设置数据库更改日志表名称 FLW_EV_DATABASECHANGELOGdatabase.setDatabaseChangeLogTableName(changeLogPrefix database.getDatabaseChangeLogTableName());// 设置数据库更改日志锁定表名称 FLW_EV_DATABASECHANGELOGLOCKdatabase.setDatabaseChangeLogLockTableName(changeLogPrefix database.getDatabaseChangeLogLockTableName());String databaseSchema databaseConfiguration.getDatabaseSchema();if (StringUtils.isNotEmpty(databaseSchema)) {database.setDefaultSchemaName(databaseSchema);database.setLiquibaseSchemaName(databaseSchema);}String databaseCatalog databaseConfiguration.getDatabaseCatalog();if (StringUtils.isNotEmpty(databaseCatalog)) {database.setDefaultCatalogName(databaseCatalog);database.setLiquibaseCatalogName(databaseCatalog);}return new Liquibase(changeLogFile, new ClassLoaderResourceAccessor(), database);} catch (Exception e) {// We only close the connection if an exception occurred, otherwise the Liquibase instance cannot be usedif (jdbcConnection ! null closeConnection) {jdbcConnection.close();}throw new FlowableException(Error creating context liquibase instance, e);}}liquibase.database.DatabaseFactory#findCorrectDatabaseImplementation 实例化所有实现了AbstractJdbcDatabase的Database根据数据库连接获取数据库实现 public Database findCorrectDatabaseImplementation(DatabaseConnection connection) throws DatabaseException {// 实例化所有实现了AbstractJdbcDatabase的DatabaseSortedSetDatabase foundDatabases new TreeSet(new DatabaseComparator());Iterator var3 this.getImplementedDatabases().iterator();while(var3.hasNext()) {Database implementedDatabase (Database)var3.next();if (connection instanceof OfflineConnection) {if (((OfflineConnection)connection).isCorrectDatabaseImplementation(implementedDatabase)) {foundDatabases.add(implementedDatabase);}// 通过连接的数据库产品名判断 return DM DBMS.equalsIgnoreCase(conn.getDatabaseProductName());} else if (implementedDatabase.isCorrectDatabaseImplementation(connection)) {foundDatabases.add(implementedDatabase);}}// 没有找到实现if (foundDatabases.isEmpty()) {LOG.warning(Unknown database: connection.getDatabaseProductName());// 返回一个不支持的数据库UnsupportedDatabase unsupportedDB new UnsupportedDatabase();// 设置连接unsupportedDB.setConnection(connection);return unsupportedDB;} else {Database returnDatabase;try {returnDatabase (Database)((Database)foundDatabases.iterator().next()).getClass().getConstructor().newInstance();} catch (Exception var5) {throw new UnexpectedLiquibaseException(var5);}returnDatabase.setConnection(connection);return returnDatabase;}}没有达梦数据库实现返回一个不支持的数据库实例 设置连接时执行报错 解决
liquibase.database.DatabaseFactory 查看实例化Database方式 liquibase.servicelocator.StandardServiceLocator#findInstances 通过Java SPI机制实现 所以根据SPI实现方式 创建达梦数据库实现 暂且放在业务工程中后面可以搞一个单独的集成工程 或 直接添加到flowable源码中
创建AbstractJdbcDatabase实现类DMDatabase 参考liquibase.database.core.OracleDatabase实现修改
package com.xxxx.workflow.database;/*** Author Chow* Date 2024/12/27 17:44* Version 1.0* description**/
public class DMDatabase extends AbstractJdbcDatabase {public static final Pattern PROXY_USER Pattern.compile(.*(?:thin|oci)\\:(.)/.*);/*** 产品名称*/public static final String PRODUCT_NAME DM DBMS;private static ResourceBundle coreBundle ResourceBundle.getBundle(liquibase/i18n/liquibase-core);protected final int SHORT_IDENTIFIERS_LENGTH 30;protected final int LONG_IDENTIFIERS_LEGNTH 128;public static final int ORACLE_12C_MAJOR_VERSION 12;private SetString reservedWords new HashSet();private SetString userDefinedTypes;private MapString, String savedSessionNlsSettings;private Boolean canAccessDbaRecycleBin;private Integer databaseMajorVersion;private Integer databaseMinorVersion;public DMDatabase() {super.unquotedObjectsAreUppercased true;super.setCurrentDateTimeFunction(SYSTIMESTAMP);this.dateFunctions.add(new DatabaseFunction(SYSDATE));this.dateFunctions.add(new DatabaseFunction(SYSTIMESTAMP));this.dateFunctions.add(new DatabaseFunction(CURRENT_TIMESTAMP));super.sequenceNextValueFunction %s.nextval;super.sequenceCurrentValueFunction %s.currval;}Overridepublic int getPriority() {return 1;}private void tryProxySession(String url, Connection con) {Matcher m PROXY_USER.matcher(url);if (m.matches()) {Properties props new Properties();props.put(PROXY_USER_NAME, m.group(1));Method method;try {method con.getClass().getMethod(openProxySession, Integer.TYPE, Properties.class);method.setAccessible(true);method.invoke(con, 1, props);} catch (Exception var8) {Scope.getCurrentScope().getLog(this.getClass()).info(Could not open proxy session on DMDatabase: var8.getCause().getMessage());return;}try {method con.getClass().getMethod(isProxySession);method.setAccessible(true);boolean b (Boolean) method.invoke(con);if (!b) {Scope.getCurrentScope().getLog(this.getClass()).info(Proxy session not established on DMDatabase: );}} catch (Exception var7) {Scope.getCurrentScope().getLog(this.getClass()).info(Could not open proxy session on DMDatabase: var7.getCause().getMessage());}}}Overridepublic void setConnection(DatabaseConnection conn) {this.reservedWords.addAll(Arrays.asList(GROUP, USER, SESSION, PASSWORD, RESOURCE, START, SIZE, UID, DESC, ORDER));Connection sqlConn null;if (!(conn instanceof OfflineConnection)) {try {if (conn instanceof JdbcConnection) {sqlConn ((JdbcConnection) conn).getWrappedConnection();}} catch (Exception var29) {throw new UnexpectedLiquibaseException(var29);}if (sqlConn ! null) {this.tryProxySession(conn.getURL(), sqlConn);try {this.reservedWords.addAll(Arrays.asList(sqlConn.getMetaData().getSQLKeywords().toUpperCase().split(,\\s*)));} catch (SQLException var28) {Scope.getCurrentScope().getLog(this.getClass()).info(Could get sql keywords on DMDatabase: var28.getMessage());}/*** 在Oracle数据库中setRemarksReporting是一个用于设置数据库对象如表、视图、列等注释或描述的方法。这通常用于生成数据库文档。*/try {Method method sqlConn.getClass().getMethod(setRemarksReporting, Boolean.TYPE);method.setAccessible(true);method.invoke(sqlConn, true);} catch (Exception var27) {Scope.getCurrentScope().getLog(this.getClass()).info(Could not set remarks reporting on DMDatabase: var27.getMessage());}CallableStatement statement null;// 基于oracle的实现修改 存储过程问题无效的方法名[DB_VERSION] 这里直接写死String sql;try {DatabaseMetaData metaData sqlConn.getMetaData();Connection connection metaData.getConnection();Connection connection1 connection.getMetaData().getConnection();//String compatibleVersion 11.2.0.4.0; //这个是oracleDatabase 当前使用的数据库版本String compatibleVersion 8.1.3.100;Matcher majorVersionMatcher Pattern.compile((\\d)\\.(\\d)\\..*).matcher(compatibleVersion);if (majorVersionMatcher.matches()) {this.databaseMajorVersion Integer.valueOf(majorVersionMatcher.group(1));this.databaseMinorVersion Integer.valueOf(majorVersionMatcher.group(2));}} catch (SQLException var25) {sql Cannot read from DBMS_UTILITY.DB_VERSION: var25.getMessage();Scope.getCurrentScope().getLog(this.getClass()).info(Could not set check compatibility mode on DMDatabase, assuming not running in any sort of compatibility mode: sql);} finally {JdbcUtil.closeStatement(statement);}if (GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue() ! null) {int timeoutValue (Integer) GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue();Scope.getCurrentScope().getLog(this.getClass()).fine(Setting DDL_LOCK_TIMEOUT value to timeoutValue);sql ALTER SESSION SET DDL_LOCK_TIMEOUT timeoutValue;PreparedStatement ddlLockTimeoutStatement null;try {ddlLockTimeoutStatement sqlConn.prepareStatement(sql);ddlLockTimeoutStatement.execute();} catch (SQLException var23) {Scope.getCurrentScope().getUI().sendErrorMessage(Unable to set the DDL_LOCK_TIMEOUT_VALUE: var23.getMessage(), var23);Scope.getCurrentScope().getLog(this.getClass()).warning(Unable to set the DDL_LOCK_TIMEOUT_VALUE: var23.getMessage(), var23);} finally {JdbcUtil.closeStatement(ddlLockTimeoutStatement);}}}}super.setConnection(conn);}/*** 简称* return*/Overridepublic String getShortName() {return dm;}/*** 默认数据库产品名称* return*/Overrideprotected String getDefaultDatabaseProductName() {return DM DBMS;}Overridepublic int getDatabaseMajorVersion() throws DatabaseException {return this.databaseMajorVersion null ? super.getDatabaseMajorVersion() : this.databaseMajorVersion;}Overridepublic int getDatabaseMinorVersion() throws DatabaseException {return this.databaseMinorVersion null ? super.getDatabaseMinorVersion() : this.databaseMinorVersion;}/*** 端口* return*/Overridepublic Integer getDefaultPort() {return 5236;}Overridepublic String getJdbcCatalogName(CatalogAndSchema schema) {return null;}Overridepublic String getJdbcSchemaName(CatalogAndSchema schema) {return this.correctObjectName(schema.getCatalogName() null ? schema.getSchemaName() : schema.getCatalogName(), Schema.class);}Overrideprotected String getAutoIncrementClause(String generationType, Boolean defaultOnNull) {if (StringUtil.isEmpty(generationType)) {return super.getAutoIncrementClause();} else {String autoIncrementClause GENERATED %s AS IDENTITY;String generationStrategy generationType;if (Boolean.TRUE.equals(defaultOnNull) generationType.toUpperCase().equals(BY DEFAULT)) {generationStrategy generationType ON NULL;}return String.format(autoIncrementClause, generationStrategy);}}Overridepublic String generatePrimaryKeyName(String tableName) {return tableName.length() 27 ? PK_ tableName.toUpperCase(Locale.US).substring(0, 27) : PK_ tableName.toUpperCase(Locale.US);}Overridepublic boolean supportsInitiallyDeferrableColumns() {return true;}Overridepublic boolean isReservedWord(String objectName) {return this.reservedWords.contains(objectName.toUpperCase());}Overridepublic boolean supportsSequences() {return true;}Overridepublic boolean supportsSchemas() {return false;}Overrideprotected String getConnectionCatalogName() throws DatabaseException {if (this.getConnection() instanceof OfflineConnection) {return this.getConnection().getCatalog();} else if (!(this.getConnection() instanceof JdbcConnection)) {return this.defaultCatalogName;} else {try {return (String) ((ExecutorService) Scope.getCurrentScope().getSingleton(ExecutorService.class)).getExecutor(jdbc, this).queryForObject(new RawCallStatement(select sys_context( userenv, current_schema ) from dual), String.class);} catch (Exception var2) {Scope.getCurrentScope().getLog(this.getClass()).info(Error getting default schema, var2);return null;}}}/*** 根据数据库连接判断是否是该数据库实现* {link liquibase.database.DatabaseFactory#findCorrectDatabaseImplementation(liquibase.database.DatabaseConnection)}* {link Database#isCorrectDatabaseImplementation(DatabaseConnection)}* param conn* return* throws DatabaseException*/Overridepublic boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {return DM DBMS.equalsIgnoreCase(conn.getDatabaseProductName());}/*** jdbc 驱动* param url* return*/Overridepublic String getDefaultDriver(String url) {return url.startsWith(jdbc:dm) ? dm.jdbc.driver.DmDriver : null;}Overridepublic String getDefaultCatalogName() {String defaultCatalogName super.getDefaultCatalogName();if (Boolean.TRUE.equals(GlobalConfiguration.PRESERVE_SCHEMA_CASE.getCurrentValue())) {return defaultCatalogName;} else {return defaultCatalogName null ? null : defaultCatalogName.toUpperCase(Locale.US);}}Overridepublic String getDateLiteral(String isoDate) {String normalLiteral super.getDateLiteral(isoDate);if (this.isDateOnly(isoDate)) {return TO_DATE( normalLiteral , YYYY-MM-DD);} else if (this.isTimeOnly(isoDate)) {return TO_DATE( normalLiteral , HH24:MI:SS);} else if (this.isTimestamp(isoDate)) {return TO_TIMESTAMP( normalLiteral , YYYY-MM-DD HH24:MI:SS.FF);} else if (this.isDateTime(isoDate)) {int seppos normalLiteral.lastIndexOf(46);if (seppos ! -1) {normalLiteral normalLiteral.substring(0, seppos) ;}return TO_DATE( normalLiteral , YYYY-MM-DD HH24:MI:SS);} else {return UNSUPPORTED: isoDate;}}Overridepublic boolean isSystemObject(DatabaseObject example) {if (example null) {return false;} else if (this.isLiquibaseObject(example)) {return false;} else {if (example instanceof Schema) {label131:{if (!SYSTEM.equals(example.getName()) !SYS.equals(example.getName()) !CTXSYS.equals(example.getName()) !XDB.equals(example.getName())) {if (!SYSTEM.equals(example.getSchema().getCatalogName()) !SYS.equals(example.getSchema().getCatalogName()) !CTXSYS.equals(example.getSchema().getCatalogName()) !XDB.equals(example.getSchema().getCatalogName())) {break label131;}return true;}return true;}} else if (this.isSystemObject(example.getSchema())) {return true;}if (example instanceof Catalog) {if (SYSTEM.equals(example.getName()) || SYS.equals(example.getName()) || CTXSYS.equals(example.getName()) || XDB.equals(example.getName())) {return true;}} else if (example.getName() ! null) {if (example.getName().startsWith(BIN$)) {boolean filteredInOriginalQuery this.canAccessDbaRecycleBin();if (!filteredInOriginalQuery) {filteredInOriginalQuery StringUtil.trimToEmpty(example.getSchema().getName()).equalsIgnoreCase(this.getConnection().getConnectionUserName());}if (!filteredInOriginalQuery) {return true;}return !(example instanceof PrimaryKey) !(example instanceof Index) !(example instanceof UniqueConstraint);}if (example.getName().startsWith(AQ$)) {return true;}if (example.getName().startsWith(DR$)) {return true;}if (example.getName().startsWith(SYS_IOT_OVER)) {return true;}if ((example.getName().startsWith(MDRT_) || example.getName().startsWith(MDRS_)) example.getName().endsWith($)) {return true;}if (example.getName().startsWith(MLOG$_)) {return true;}if (example.getName().startsWith(RUPD$_)) {return true;}if (example.getName().startsWith(WM$_)) {return true;}if (CREATE$JAVA$LOB$TABLE.equals(example.getName())) {return true;}if (JAVA$CLASS$MD5$TABLE.equals(example.getName())) {return true;}if (example.getName().startsWith(ISEQ$$_)) {return true;}if (example.getName().startsWith(USLOG$)) {return true;}if (example.getName().startsWith(SYS_FBA)) {return true;}}return super.isSystemObject(example);}}Overridepublic boolean supportsTablespaces() {return true;}Overridepublic boolean supportsAutoIncrement() {boolean isAutoIncrementSupported false;try {if (this.getDatabaseMajorVersion() 12) {isAutoIncrementSupported true;}} catch (DatabaseException var3) {isAutoIncrementSupported false;}return isAutoIncrementSupported;}Overridepublic boolean supportsRestrictForeignKeys() {return false;}Overridepublic int getDataTypeMaxParameters(String dataTypeName) {if (BINARY_FLOAT.equals(dataTypeName.toUpperCase())) {return 0;} else {return BINARY_DOUBLE.equals(dataTypeName.toUpperCase()) ? 0 : super.getDataTypeMaxParameters(dataTypeName);}}public String getSystemTableWhereClause(String tableNameColumn) {ListString clauses new ArrayList(Arrays.asList(BIN$, AQ$, DR$, SYS_IOT_OVER, MLOG$_, RUPD$_, WM$_, ISEQ$$_, USLOG$, SYS_FBA));for (int i 0; i clauses.size(); i) {clauses.set(i, tableNameColumn NOT LIKE (String) clauses.get(i) %);}return ( StringUtil.join(clauses, AND ) );}Overridepublic boolean jdbcCallsCatalogsSchemas() {return true;}public SetString getUserDefinedTypes() {if (this.userDefinedTypes null) {this.userDefinedTypes new HashSet();if (this.getConnection() ! null !(this.getConnection() instanceof OfflineConnection)) {try {try {this.userDefinedTypes.addAll(((ExecutorService) Scope.getCurrentScope().getSingleton(ExecutorService.class)).getExecutor(jdbc, this).queryForList(new RawSqlStatement(SELECT DISTINCT TYPE_NAME FROM ALL_TYPES), String.class));} catch (DatabaseException var2) {this.userDefinedTypes.addAll(((ExecutorService) Scope.getCurrentScope().getSingleton(ExecutorService.class)).getExecutor(jdbc, this).queryForList(new RawSqlStatement(SELECT TYPE_NAME FROM USER_TYPES), String.class));}} catch (DatabaseException var3) {}}}return this.userDefinedTypes;}Overridepublic String generateDatabaseFunctionValue(DatabaseFunction databaseFunction) {if (databaseFunction ! null current_timestamp.equalsIgnoreCase(databaseFunction.toString())) {return databaseFunction.toString();} else if (!(databaseFunction instanceof SequenceNextValueFunction) !(databaseFunction instanceof SequenceCurrentValueFunction)) {return super.generateDatabaseFunctionValue(databaseFunction);} else {String quotedSeq super.generateDatabaseFunctionValue(databaseFunction);return quotedSeq.replaceFirst(\([^.\])\\.([^.\])\, \$1\.\$2\);}}Overridepublic ValidationErrors validate() {ValidationErrors errors super.validate();DatabaseConnection connection this.getConnection();if (connection ! null !(connection instanceof OfflineConnection)) {if (!this.canAccessDbaRecycleBin()) {errors.addWarning(this.getDbaRecycleBinWarning());}return errors;} else {Scope.getCurrentScope().getLog(this.getClass()).info(Cannot validate offline database);return errors;}}public String getDbaRecycleBinWarning() {return Liquibase needs to access the DBA_RECYCLEBIN table so we can automatically handle the case where constraints are deleted and restored. Since Oracle doesnt properly restore the original table names referenced in the constraint, we use the information from the DBA_RECYCLEBIN to automatically correct this issue.\n\nThe user you used to connect to the database ( this.getConnection().getConnectionUserName() ) needs to have \SELECT ON SYS.DBA_RECYCLEBIN\ permissions set before we can perform this operation. Please run the following SQL to set the appropriate permissions, and try running the command again.\n\n GRANT SELECT ON SYS.DBA_RECYCLEBIN TO this.getConnection().getConnectionUserName() ;;}public boolean canAccessDbaRecycleBin() {if (this.canAccessDbaRecycleBin null) {DatabaseConnection connection this.getConnection();if (connection null || connection instanceof OfflineConnection) {return false;}Statement statement null;try {statement ((JdbcConnection) connection).createStatement();ResultSet resultSet statement.executeQuery(select 1 from dba_recyclebin where 01);resultSet.close();this.canAccessDbaRecycleBin true;} catch (Exception var7) {if (var7 instanceof SQLException var7.getMessage().startsWith(ORA-00942)) {this.canAccessDbaRecycleBin false;} else {Scope.getCurrentScope().getLog(this.getClass()).warning(Cannot check dba_recyclebin access, var7);this.canAccessDbaRecycleBin false;}} finally {JdbcUtil.close((ResultSet) null, statement);}}return this.canAccessDbaRecycleBin;}Overridepublic boolean supportsNotNullConstraintNames() {return true;}public boolean isValidOracleIdentifier(String identifier, Class? extends DatabaseObject type) {if (identifier ! null identifier.length() 1) {if (!identifier.matches(^(i?)[A-Z][A-Z0-9\\$\\_\\#]*$)) {return false;} else {return identifier.length() 128;}} else {return false;}}public int getIdentifierMaximumLength() {try {if (this.getDatabaseMajorVersion() 12) {return 30;} else {return this.getDatabaseMajorVersion() 12 this.getDatabaseMinorVersion() 1 ? 30 : 128;}} catch (DatabaseException var2) {throw new UnexpectedLiquibaseException(Cannot determine the DM database version number, var2);}}
}
新建META-INF/services/liquibase.database.Database文件添加DMDatabase全路径名 再次运行可以找到dm数据库实现 进入else 问题二找不到 setRemarksReporting 方法
Could not set remarks reporting on OracleDatabase: jdk.proxy2.$Proxy147.setRemarksReporting(boolean)
Method threw ‘java.lang.NoSuchMethodException’ exception. 找不到 setRemarksReporting 方法
定位
com.xxxx.workflow.database.DMDatabase#setConnection 解决
反射调用了 JDBC 连接对象setRemarksReporting 方法
Oracle数据库中 setRemarksReporting用于设置数据库对象注释的方法用来生成数据库文档。
这个dm的数据库实现可以直接注释
问题三存储过程问题问题Cannot read from DBMS_UTILITY.DB_VERSION: 无效的方法名[DB_VERSION]
Could not set check compatibility mode on OracleDatabase, assuming not running in any sort of compatibility mode: Cannot read from DBMS_UTILITY.DB_VERSION: 第1 行附近出现错误:无效的方法名[DB_VERSION]
分析
定位
com.xxxx.workflow.database.DMDatabase#setConnection 调用了存储过程
解决
达梦没有这个存储过程 这些把值写死 Overridepublic void setConnection(DatabaseConnection conn) {this.reservedWords.addAll(Arrays.asList(GROUP, USER, SESSION, PASSWORD, RESOURCE, START, SIZE, UID, DESC, ORDER));Connection sqlConn null;if (!(conn instanceof OfflineConnection)) {try {if (conn instanceof JdbcConnection) {sqlConn ((JdbcConnection) conn).getWrappedConnection();}} catch (Exception var29) {throw new UnexpectedLiquibaseException(var29);}if (sqlConn ! null) {this.tryProxySession(conn.getURL(), sqlConn);try {this.reservedWords.addAll(Arrays.asList(sqlConn.getMetaData().getSQLKeywords().toUpperCase().split(,\\s*)));} catch (SQLException var28) {Scope.getCurrentScope().getLog(this.getClass()).info(Could get sql keywords on OracleDatabase: var28.getMessage());}try {Method method sqlConn.getClass().getMethod(setRemarksReporting, Boolean.TYPE);method.setAccessible(true);method.invoke(sqlConn, true);} catch (Exception var27) {Scope.getCurrentScope().getLog(this.getClass()).info(Could not set remarks reporting on OracleDatabase: var27.getMessage());}CallableStatement statement null;String sql;try {DatabaseMetaData metaData sqlConn.getMetaData();Connection connection metaData.getConnection();Connection connection1 connection.getMetaData().getConnection();//String compatibleVersion 11.2.0.4.0; //这个是oracleDatabase 当前使用的数据库版本String compatibleVersion 8.1.3.100;Matcher majorVersionMatcher Pattern.compile((\\d)\\.(\\d)\\..*).matcher(compatibleVersion);if (majorVersionMatcher.matches()) {this.databaseMajorVersion Integer.valueOf(majorVersionMatcher.group(1));this.databaseMinorVersion Integer.valueOf(majorVersionMatcher.group(2));}} catch (SQLException var25) {sql Cannot read from DBMS_UTILITY.DB_VERSION: var25.getMessage();Scope.getCurrentScope().getLog(this.getClass()).info(Could not set check compatibility mode on OracleDatabase, assuming not running in any sort of compatibility mode: sql);} finally {JdbcUtil.closeStatement(statement);}if (GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue() ! null) {int timeoutValue (Integer) GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue();Scope.getCurrentScope().getLog(this.getClass()).fine(Setting DDL_LOCK_TIMEOUT value to timeoutValue);sql ALTER SESSION SET DDL_LOCK_TIMEOUT timeoutValue;PreparedStatement ddlLockTimeoutStatement null;try {ddlLockTimeoutStatement sqlConn.prepareStatement(sql);ddlLockTimeoutStatement.execute();} catch (SQLException var23) {Scope.getCurrentScope().getUI().sendErrorMessage(Unable to set the DDL_LOCK_TIMEOUT_VALUE: var23.getMessage(), var23);Scope.getCurrentScope().getLog(this.getClass()).warning(Unable to set the DDL_LOCK_TIMEOUT_VALUE: var23.getMessage(), var23);} finally {JdbcUtil.closeStatement(ddlLockTimeoutStatement);}}}}super.setConnection(conn);}参考https://blog.csdn.net/zhangdaiscott/article/details/134547342 问题四: 更新事件注册表引擎表时出错、初始化事件注册表数据模型时出错 解决
将flowable.database-schema-update设置为false 应用启动时不会更新数据库模式如果数据库模式和 Flowable 版本不匹配会抛出异常阻止应用启动。
问题五验证事件注册表引擎架构时出错
liquibase.Liquibase#validate
liquibase.executor.jvm.JdbcExecutor#execute(liquibase.statement.SqlStatement, java.util.Listliquibase.sql.visitor.SqlVisitor) 解决
liquibase.Liquibase#validate 验证数据库模式与变更日志文件一致性这里直接注释掉。 数据库版本问题version mismatch: library version is ‘7.0.1.1’, db version is 7.0.0.0 解决
参考flowable源码当前版 修改为对应版本 也可以数据源先使用mysql再做迁移 启动流程相关问题
由于flowable.database-schema-update设置为false如果数据表结构等和 Flowable 版本不匹配不会进行自动更新当前表直接迁移的是原7.0.0版本的表结构源码部署的是GA版本的7.0.0分支实际版本为7.0.0.39两个版本的初始化表数量一样但表结构字段有不同。 列找不到 解决
表结构可以先使用mysql生成迁移到dm 服务启动成功日志
解决以上问题可以启动服务
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection1750724866 wrapping dm.jdbc.driver.DmdbConnection657f1fc3]]
2024-12-30 17:12:19.969 [main] INFO o.f.i.e.i.IdmEngineImpl -[init,52] - IdmEngine default created
2024-12-30 17:12:19.986 [main] INFO o.f.s.SpringProcessEngineConfiguration -[configuratorsAfterInit,1157] - Executing configure() of class org.flowable.dmn.spring.configurator.SpringDmnEngineConfigurator (priority:200000)
Opening JDBC Connection
2024-12-30 17:12:30.646 [main] INFO liquibase.database -[log,37] - Could not set remarks reporting on OracleDatabase: jdk.proxy2.$Proxy147.setRemarksReporting(boolean)
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection1026432280 wrapping dm.jdbc.driver.DmdbConnection657f1fc3]]
2024-12-30 17:12:35.406 [main] INFO o.f.d.e.i.DmnEngineImpl -[init,55] - DmnEngine default created
2024-12-30 17:12:35.415 [main] INFO o.f.s.SpringProcessEngineConfiguration -[configuratorsAfterInit,1157] - Executing configure() of class org.flowable.cmmn.spring.configurator.SpringCmmnEngineConfigurator (priority:500000)
Opening JDBC Connection
2024-12-30 17:12:45.684 [main] INFO liquibase.database -[log,37] - Could not set remarks reporting on OracleDatabase: jdk.proxy2.$Proxy147.setRemarksReporting(boolean)
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection8603972 wrapping dm.jdbc.driver.DmdbConnection657f1fc3]]
2024-12-30 17:12:52.094 [main] INFO o.f.c.e.i.CmmnEngineImpl -[init,72] - CmmnEngine default created
Opening JDBC ConnectionPreparing: select VALUE_ from ACT_GE_PROPERTY where NAME_ schema.versionParameters: Columns: VALUE_Row: 7.0.1.1Total: 1
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection530287651 wrapping dm.jdbc.driver.DmdbConnection657f1fc3]]
2024-12-30 17:12:52.443 [main] INFO o.f.e.i.ProcessEngineImpl -[init,89] - ProcessEngine default created
Opening JDBC ConnectionPreparing: select count(RES.ID_) from ACT_RE_DEPLOYMENT RES WHERE RES.ENGINE_VERSION_ ?Parameters: v5(String)Columns: COUNT(RES.ID_)Row: 0Total: 1
2024-12-30 17:12:52.937 [main] INFO o.f.e.i.c.ValidateV5EntitiesCmd -[execute,43] - Total of v5 deployments found: 0
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection871541777 wrapping dm.jdbc.driver.DmdbConnection657f1fc3]]
Opening JDBC ConnectionPreparing: select * from ACT_GE_PROPERTY where NAME_ ?Parameters: cfg.execution-related-entities-count(String)Columns: NAME_, VALUE_, REV_Row: cfg.execution-related-entities-count, true, 1Total: 1
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection1059563867 wrapping dm.jdbc.driver.DmdbConnection657f1fc3]]
Opening JDBC ConnectionPreparing: select * from ACT_GE_PROPERTY where NAME_ ?Parameters: cfg.task-related-entities-count(String)Columns: NAME_, VALUE_, REV_Row: cfg.task-related-entities-count, true, 1Total: 1....