关于单据明细仓库字段移除仓位单据引用的二开影响说明原创
金蝶云社区-邱育华
邱育华
12人赞赏了该文章 100次浏览 未经作者许可,禁止转载编辑于2024年11月09日 17:09:34
summary-icon摘要由AI智能服务提供

本文讲述了旗舰版产品中,因仓库基础资料字段上的元数据配置不当,在仓库有大量仓位时会导致内存溢出问题。11月产品迭代后,将取消元数据仓库字段对仓位字段的引用。对于二次开发程序,如直接获取仓库下所有仓位将出现异常,需按仓库id重新查询。

【背景】

经检查,旗舰版存在“仓库“基础资料字段的单据、物料库存信息等元数据上,此前勾选了“仓库下的单据体“仓位”作为引用属性时,如客户业务环境上存在一个仓库大量仓位的场景(比如:一个仓库配置有5000+的仓位数据)。如下图所示

image.png

 

由于仓库这个基础资料的结构特殊性,仓库下一个子单据体的结构用于配置存储对应的仓位信息,对仓库赋值时,操作平台底层会创建一个动态对象实体,该基础资料实体的创建过程中同步设置引用属性的值,仓位引用属性是一个单据体,同步创建了该仓库下的仓位动态对象。平台创建单据动态实体对象大小,取决于单据对象本身分录数据量,以及其元数据上设置的基础资料引用属性,在这个配置下,该单据实质上变成了一张“单据-单据分录-单据分录下仓位”的多层分录结构大对象。分录行数虽只有3500行,但仓位对象达到了3500*9000。在单据分录较多时,易造成内存溢出,引发OOM问题。


image.png


11月份产品版本迭代后,为避免这一问题,标准产品将取消元数据仓库字段上对仓位字段的引用属性的勾选。

 

【二开影响】

如果现场二开程序中,存在直接通过单据、物料上的仓库对象获取其仓库下的所有仓位的方式,如下所示:

DynamicObjectCollection locations = warehouse.getDynamicObjectCollection("entryentity");


如果二开程序的仓库对象warehouse是从单据对象上直接得到(仓库动态对象是从数据库、基础资料缓存中获取的完整对象则没有问题),取消元数据引用属性后此行代码 将提示找不到entryentity属性的异常中断。

 

修改方式:

如果二开程序存在上面情况,应修改,如果需要获取warehouse下的所有仓位,应重新根据仓库id查询:

(1) 如现场一个仓库下仓位确保不会很多(不超过100),可以根据BusinessDataServiceHelper等方法查询得到warehouse对象,如

BusinessDataServiceHelper.loadFromCache("bd_warehouse", selectProperties, qFilter);

(2) 如现场一个仓库下仓位较多,查询仓库下所有仓位的方式应注意避免查询过多内容,仅查询出仓位id即可,如下参考为批量获取多个仓库下所属仓位id的参考(返回的结果result是key为仓库id,value为仓位id集合的Map对象):

Map<Long,Set<Long>> result = new HashMap<>();
     try(DataSet locDataSet = QueryServiceHelper.queryDataSet(WarehouseLocationHelper.class.getName(), "bd_warehouse", "id, entryentity.location as locid",
       qFilter.toArray(), null)){
      for(Row row : locDataSet) {
       Long locid = row.getLong("locid");
       if(!locid.equals(0L)) {
        Long warehouseid = row.getLong("id");
        Set<Long> locids = result.getOrDefault(warehouseid, new HashSet<>());
        locids.add(locid);
        if(!result.containsKey(warehouseid)) {
            result.put(warehouseid, locids);
           }
       }
      }
     }
     
     return result;


图标赞 12
12人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!