
# 1 问题描述
调用SaveServiceHelper的saveOperate方法或者SaveServiceHelper的save方法时,抛异常:“从实体类型xxxx的属性列表查找属性失败,属性位置顺序不正确,索引位置:xx,请检查上层程序”,或者抛出这个异常:“寻找实体上xxxx对应的属性描述符失败,实体不存在此属性!”。如下图:


# 2 原因分析
导致上述异常的其中一个原因,是由于我们在进行批量保存时,会将DynamicObject[]传入save方法,如果DynamicObject[]里面的各个子元素的字段序列不一致,那么在批量保存的时候,实际用的是相同的实体类型去保存,就会导致一种能匹配,一种匹配不上。**以下面的代码为例,因为更新的数据包是查询出来的(只取了部分字段),而新增的数据包拥有全部的字段,这两个数据包的字段不一致,若将这两种数据包放到一起,进行批量保存,就会抛出上述异常。**
```
List<DynamicObject> saveList = new ArrayList<>();
// 查询出来的数据包只有部分字段
DynamicObject[] loadDynamicObjects = BusinessDataServiceHelper.load("kdec_build_materials1", "id,number,name,kdec_count,kdec_count2", new QFilter("kdec_count",QCP.equals, 10).toArray());
for (DynamicObject obj : loadDynamicObjects) {
// 更新字段值
obj.set("kdec_count2", 20);
}
// 将准备要更新数据放到saveList中
saveList.addAll(Arrays.asList(loadDynamicObjects));
// BusinessDataServiceHelper.newDynamicObject创建的对象,有全部的字段
DynamicObject newDynamicObject = BusinessDataServiceHelper.newDynamicObject("kdec_build_materials1");
newDynamicObject.set("number", "test");
newDynamicObject.set("name", "测试");
// 将新增数据放到saveList中
saveList.add(newDynamicObject);
// 将saveList转为数组
DynamicObject[] saveDynamicObject = saveList.toArray(new DynamicObject[saveList.size()]);
// 保存
OperationResult result = SaveServiceHelper.saveOperate("kdec_build_materials1", saveDynamicObject);
```
**注意**:上述的代码中,我在saveList中,先加入了准备要更新的数据,后加入了新增的数据,会抛出“从实体类型xxxx的属性列表查找属性失败...”的异常。如果将两者调换顺序,在saveList中,先加入了新增的数据,后加入了准备要更新的数据,则会抛出另一个异常:“寻找实体上xxxx对应的属性描述符失败...”。
# 3 解决方案
## 方案1:将新增的数据包,更新的数据包分开进行保存。
可参考代码如下:
```language
// 查询数据
DynamicObject[] loadDynamicObjects = BusinessDataServiceHelper.load("kdec_build_materials1", "id,number,name,kdec_count,kdec_count2", new QFilter("kdec_count",QCP.equals, 10).toArray());
for (DynamicObject obj : loadDynamicObjects) {
// 更新字段值
obj.set("kdec_count2", 20);
}
// 保存更新数据
OperationResult result = SaveServiceHelper.saveOperate("kdec_build_materials1", loadDynamicObjects);
// 创建Dynami