记一次使用DynamicObjectSerializeUtil对实体对象序列化和反序列化遇到的坑原创
金蝶云社区-zhiwei_xing
zhiwei_xing
4人赞赏了该文章 1,480次浏览 未经作者许可,禁止转载编辑于2022年12月24日 23:37:06

需求如下:从第三方数据库抓取数据批量生成二开单据,此过程中需要根据基础资料编码获取基础资料对象,进行表单实例化对象的构建。在批量构建实例化时,需要多次根据基础资料编码从数据库查询数据,为了提高效率,此时就想到了用缓存解决,将从数据库查出的基础资料对象放入Redis缓存中,因此就用到了DynamicObjectSerializeUtil,对基础资料进行序列化存入Redis缓存和反序列化从Redis缓存取基础资料对象。不过后续发现可以使用标准的BusinessDataServiceHelper.loadSingleFromCache即可解决从缓存取数的需求,但还是记录一下使用Redis缓存和DynamicObjectSerializeUtil的用法。

过程如下:

IAppCache appCache = AppCache.get("bgm");
//实体类型 此处用币别演示
DynamicObjectType dtType = EntityMetadataCache.getDataEntityType("bd_currency");
//查询基础资料对象
QFilter filter = new QFilter("number", QCP.equals, "CNY");
DynamicObject obj = QueryServiceHelper.queryOne("bd_currency", "id,number,name,status,enable", filter.toArray());
//序列化
String objectSerialization = DynamicObjectSerializeUtil.serialize(new Object[]{obj}, dtType);
//存入缓存
appCache.put("CNY", objectSerialization);


//根据基础资料编码从缓存取数据
String cacheString = appCache.get("CNY", String.class);
//反序列化
Object[] cacheObject = DynamicObjectSerializeUtil.deserialize(cacheString, dtType);
//对于单个对象数据直接获取设值
obj = (DynamicObject) cacheObject[0];

以上在反序列化时,抛出异常:kd.bos.dataentity.exception.SerializationException: 未能找到PlainObject对应的数据类型,请检查是否Json字符串和类型注册时机:序列化,如图:image.png

经过调试,发现QueryServiceHelper.queryOne查询出的基础资料为平铺对象"PlainObject",并不是实际的基础资料对象,如图:

image.png

所以,从数据库查询实体对象进行序列化时,不能用QueryServiceHelper.queryOne,而要用

BusinessDataServiceHelper.loadSingle方法。

BusinessDataServiceHelperQueryServiceHelper的区别可以查看【性能规范】

https://developer.kingdee.com/article/241159931985186560?productLineId=29&isKnowledge=2

赞 4