美文网首页
58 Activiti7.1.0.M4兼容达梦8数据库

58 Activiti7.1.0.M4兼容达梦8数据库

作者: 滔滔逐浪 | 来源:发表于2024-01-07 08:30 被阅读0次

    Activiti7.1.0.M4兼容达梦8数据库
    前言
    报错分析
    解决方案
    代码修改
    1.ProcessEngineConfigurationImpl类添加成员变量
    1.1 修改EntityManagerSessionFactory类添加构造方法
    2.ProcessEngineConfigurationImpl类修改方法getDefaultDatabaseTypeMappings()
    3.DbSqlSessionFactory类修改方法initBulkInsertEnabledMap()
    4.AbstractQuery类修改方法addOrder()
    5.ProcessEngineConfigurationImpl类修改方法initSqlSessionFactory()
    至此全篇结束,快去起项目吧
    ————————————————
    前言
    最近在做国产化测试,activiti的服务配置完达梦相关的依赖和连接串后,启动时报错:nested exception is org.activiti.engine.ActivitiException: couldn’t deduct database type from database product name ‘DM DBMS’

    原因是:activiti7内置的数据库类型不支持达梦数据库

    故而修改activiti的源码对达梦数据库做相关适配

    报错分析
    activiti源码里并没有兼容达梦数据库,根据报错的位置跟进源码就能找到痕迹:


    image.png

    解决方案
    经过以上分析,发现需要修改源码
    在jar包中找到相关的文件,拷贝到项目中的相同路径下(一定是相同路径,这样才能在类加载器的加载顺序下覆盖jar中的class),修改代码以做适配。
    涉及修改的文件如下:


    image.png

    代码修改

    1.ProcessEngineConfigurationImpl类添加成员变量

    org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl中添加达梦的成员变量

        // 适配达梦数据库
        public static final String DATABASE_TYPE_DM = "dm";//达梦
    
    
    image.png

    1.1 修改EntityManagerSessionFactory类添加构造方法
    这里比较坑,ProcessEngineConfigurationImpl类的源码可能有bug(maybe?),不想管太多,粗暴解决吧。

    在org.activiti.engine.impl.variable.EntityManagerSessionFactory中添加构造方法(好像还引入了另一个jar依赖:javax.persistence.javax.persistence-api)

     public EntityManagerSessionFactory(EntityManagerFactory entityManagerFactory, boolean handleTransactions, boolean closeEntityManager) {
            if (entityManagerFactory == null) {
                throw new ActivitiIllegalArgumentException("entityManagerFactory is null");
            } else if (!(entityManagerFactory instanceof EntityManagerFactory)) {
                throw new ActivitiIllegalArgumentException("EntityManagerFactory must implement 'javax.persistence.EntityManagerFactory'");
            } else {
                this.entityManagerFactory = (EntityManagerFactory)entityManagerFactory;
                this.handleTransactions = handleTransactions;
                this.closeEntityManager = closeEntityManager;
            }
        }
    
    
    image.png

    3.DbSqlSessionFactory类修改方法initBulkInsertEnabledMap()
    org.activiti.engine.impl.db.DbSqlSessionFactory#initBulkInsertEnabledMap修改判断方法

       // 适配达梦数据库
            if ("oracle".equals(databaseType) || "dm".equals(databaseType)) {//达梦支持
                bulkInsertableMap.put(EventLogEntryEntityImpl.class, Boolean.FALSE);
            }
    
    
    image.png

    4.AbstractQuery类修改方法addOrder()
    org.activiti.engine.impl.AbstractQuery#addOrder修改判断方法
    此处为后来者方便,贴了整个方法的代码

        // 此处为后来者方便,贴了整个方法的代码
       protected void addOrder(String column, String sortOrder, NullHandlingOnOrder nullHandlingOnOrder) {
    
            if (orderBy == null) {
                orderBy = "";
            } else {
                orderBy = orderBy + ", ";
            }
    
            String defaultOrderByClause = column + " " + sortOrder;
    
            // 适配达梦数据库
            if (nullHandlingOnOrder != null) {
                if (nullHandlingOnOrder.equals(NullHandlingOnOrder.NULLS_FIRST)) {
                    if (ProcessEngineConfigurationImpl.DATABASE_TYPE_H2.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_HSQL.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_POSTGRES.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_ORACLE.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_DM.equals(databaseType)) // 适配达梦数据库
                    {
                        orderBy = orderBy + defaultOrderByClause + " NULLS FIRST";
                    } else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL.equals(databaseType)) {
                        orderBy = orderBy + "isnull(" + column + ") desc," + defaultOrderByClause;
                    } else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_DB2.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_MSSQL.equals(databaseType)) {
                        orderBy = orderBy + "case when " + column + " is null then 0 else 1 end," + defaultOrderByClause;
                    } else {
                        orderBy = orderBy + defaultOrderByClause;
                    }
    
                } else if (nullHandlingOnOrder.equals(NullHandlingOnOrder.NULLS_LAST)) {
                    if (ProcessEngineConfigurationImpl.DATABASE_TYPE_H2.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_HSQL.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_POSTGRES.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_ORACLE.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_DM.equals(databaseType)) // 适配达梦数据库
                    {
                        orderBy = orderBy + column + " " + sortOrder + " NULLS LAST";
                    } else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL.equals(databaseType)) {
                        orderBy = orderBy + "isnull(" + column + ") asc," + defaultOrderByClause;
                    } else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_DB2.equals(databaseType)
                            || ProcessEngineConfigurationImpl.DATABASE_TYPE_MSSQL.equals(databaseType)) {
                        orderBy = orderBy + "case when " + column + " is null then 1 else 0 end," + defaultOrderByClause;
                    } else {
                        orderBy = orderBy + defaultOrderByClause;
                    }
                }
            } else {
                orderBy = orderBy + defaultOrderByClause;
            }
    
        }
    
    

    5.ProcessEngineConfigurationImpl类修改方法initSqlSessionFactory()
    这一步很重要(参考了不少博主的文章,这一步是其他很多博主忽略了的步骤,自己踩了坑才知道),不然要报:org.activiti.engine.ActivitiException: resource ‘org/activiti/db/create/activiti.dm.create.engine.sql’ is not available

    org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl#initSqlSessionFactory添加判断逻辑

        if (databaseType != null) {
                        if (DATABASE_TYPE_DM.equals(databaseType)){
                            properties.load(getResourceAsStream("org/activiti/db/properties/" + DATABASE_TYPE_ORACLE + ".properties"));
                        }else {
                            properties.load(getResourceAsStream("org/activiti/db/properties/" + databaseType + ".properties"));
                        }
                    }
    
    
    image.png

    至此全篇结束,快去起项目吧!

    相关文章

      网友评论

          本文标题:58 Activiti7.1.0.M4兼容达梦8数据库

          本文链接:https://www.haomeiwen.com/subject/zzdgndtx.html