Salesforce System.TypeException:单个操作中不能有超过10个块

Salesforce System.TypeException:单个操作中不能有超过10个块,salesforce,apex-code,apex,Salesforce,Apex Code,Apex,我有一个非常奇怪的错误,“System.TypeException:在一个操作中不能有超过10个块”,以前有人见过/遇到过这个错误吗?如果你知道如何解决这个问题,请你指导我 我正在尝试将不同类型的sObject一起插入sObject列表中。列表的行数永远不会超过10行 这里的帖子: 表明导致超出此块限制的不是不同对象的数量,而是对象的顺序。换句话说,“1,1,1,2,2”有一个组块,即从“1”到“2”的过渡。“1,2,3,4,5,6”有六个块,尽管元素的数量相同。建议将对象放入按对象顺序排序的

我有一个非常奇怪的错误,“System.TypeException:在一个操作中不能有超过10个块”,以前有人见过/遇到过这个错误吗?如果你知道如何解决这个问题,请你指导我

我正在尝试将不同类型的sObject一起插入sObject列表中。列表的行数永远不会超过10行

这里的帖子:

表明导致超出此块限制的不是不同对象的数量,而是对象的顺序。换句话说,“1,1,1,2,2”有一个组块,即从“1”到“2”的过渡。“1,2,3,4,5,6”有六个块,尽管元素的数量相同。建议将对象放入按对象顺序排序的列表中

您是否可以创建一个只有2行或3行的合理测试用例?

本文如下:

表明导致超出此块限制的不是不同对象的数量,而是对象的顺序。换句话说,“1,1,1,2,2”有一个组块,即从“1”到“2”的过渡。“1,2,3,4,5,6”有六个块,尽管元素的数量相同。建议将对象放入按对象顺序排序的列表中

您是否可以创建一个只有2行或3行的合理测试用例?

本文如下:

表明导致超出此块限制的不是不同对象的数量,而是对象的顺序。换句话说,“1,1,1,2,2”有一个组块,即从“1”到“2”的过渡。“1,2,3,4,5,6”有六个块,尽管元素的数量相同。建议将对象放入按对象顺序排序的列表中

您是否可以创建一个只有2行或3行的合理测试用例?

本文如下:

表明导致超出此块限制的不是不同对象的数量,而是对象的顺序。换句话说,“1,1,1,2,2”有一个组块,即从“1”到“2”的过渡。“1,2,3,4,5,6”有六个块,尽管元素的数量相同。建议将对象放入按对象顺序排序的列表中


您是否可以创建一个只有2行或3行的合理测试用例?

对于这个问题有两种可能的解释:

  • 正如Jagular所指出的,您没有对尝试插入的Sobject排序,因此列表中有10多个“chunk”
  • 您尝试插入>2000条记录和>1个对象类型。这似乎是Salesforce的错误,因为错误消息与问题不匹配

  • 对此问题有两种可能的解释:

  • 正如Jagular所指出的,您没有对尝试插入的Sobject排序,因此列表中有10多个“chunk”
  • 您尝试插入>2000条记录和>1个对象类型。这似乎是Salesforce的错误,因为错误消息与问题不匹配

  • 对此问题有两种可能的解释:

  • 正如Jagular所指出的,您没有对尝试插入的Sobject排序,因此列表中有10多个“chunk”
  • 您尝试插入>2000条记录和>1个对象类型。这似乎是Salesforce的错误,因为错误消息与问题不匹配

  • 对此问题有两种可能的解释:

  • 正如Jagular所指出的,您没有对尝试插入的Sobject排序,因此列表中有10多个“chunk”
  • 您尝试插入>2000条记录和>1个对象类型。这似乎是Salesforce的错误,因为错误消息与问题不匹配

  • 场景1及其解决方案

    使用混合列表时,请确保对象不会以任何顺序分散。例如,A,B,A,B,A,B,A,B…。Salesforce在切换sObject类型10次以上时存在固有的问题。他们把这种转换限制称为分块限制。所以,在这个混合列表中,如果您对它进行排序,然后将其传递给DML,Salesforce会更高兴。例如A、 A、A、A、B、B、B……在这种情况下,salesforce只需切换一次(即读取所有A对象–>切换–>读取所有B对象)。最大区块限制为10。所以,我们安全了。 listToUpdate.sort(); 更新列表更新

    场景2及其解决方案

    我们必须记住的另一点是,如果混合列表包含一种类型的更多对象,我们可能会遇到TypeException。如屏幕截图中所述,如果列表包含1001个A型对象和1001个B型对象,则对象总数等于2002。允许的最大块数为10。因此,如果你做一个简单的数学计算,每个区块中的对象数量将是2002/10=200。Salesforce还强制执行另一个调控器限制,即每个区块不应包含200个或超过200个对象。在这种情况下,我们必须预见有多少对象可能会进入该代码,并且每次都必须编写代码来传递DML的安全大小列表。 情景3及其解决方案

    场景3及其解决方案

    第三种可能发生的情况是,如果混合列表包含10种以上类型的对象,那么即使列表的大小非常小,当salesforce读取不同的sObject时也会发生切换。因此,我们必须确保在这种情况下,我们为每个sObject类型分配单独的列表,然后将其传递给DML。在apex触发器或apex类中执行此操作会给您带来一些麻烦,因为在一个上下文中启动了多个DML。在不同的上下文中为DML操作传递这种类型的多个sObject列表将真正减轻平台的负载。考虑在批处理APEX作业中使用这种逻辑,而不是APEX触发器或APEX类。 希望这能有所帮助。

    场景1及其
        private static void saveSobjectSet(List <Sobject> listToUpdate) {
        Integer SFDC_CHUNK_LIMIT = 10;
    
        // Developed this part due to System.TypeException: Cannot have more than 10 chunks in a single operation
        Map<String, List<Sobject>> sortedMapPerObjectType = new Map<String, List<Sobject>>();
        Map<String, Integer> numberOf200ChunkPerObject = new Map<String, Integer>();
        for (Sobject obj : listToUpdate) {
            String objTypeREAL = String.valueOf(obj.getSObjectType());
    
            if (! numberOf200ChunkPerObject.containsKey(objTypeREAL)){
                numberOf200ChunkPerObject.put(objTypeREAL, 1);
            }
            // Number of 200 chunk for a given Object
            Integer numnberOf200Record = numberOf200ChunkPerObject.get(objTypeREAL);
            // Object type + number of 200 records chunk
            String objTypeCURRENT = String.valueOf(obj.getSObjectType()) + String.valueOf(numnberOf200Record);
            // CurrentList
            List<sObject> currentList = sortedMapPerObjectType.get(objTypeCURRENT);
    
            if (currentList == null || currentList.size() > 199) {
               if(currentList != null && currentList.size() > 199){
                    numberOf200ChunkPerObject.put(objTypeREAL, numnberOf200Record + 1);
                    objTypeCURRENT = String.valueOf(obj.getSObjectType()) + String.valueOf(numnberOf200Record);            
                }
                sortedMapPerObjectType.put(objTypeCURRENT, new List<Sobject>());
            }
            sortedMapPerObjectType.get(objTypeCURRENT).add(obj);
        }
        while(sortedMapPerObjectType.size() > 0) {
            // Create a new list, which can contain a max of chunking limit, and sorted, so we don't get any errors 
            List<Sobject> safeListForChunking = new List<Sobject>();
            List<String> keyListSobjectType = new List<String>(sortedMapPerObjectType.keySet());
            for (Integer i = 0;i<SFDC_CHUNK_LIMIT && !sortedMapPerObjectType.isEmpty();i++) {
                List<Sobject> listSobjectOfOneType = sortedMapPerObjectType.remove(keyListSobjectType.remove(0)); 
                safeListForChunking.addAll(listSobjectOfOneType);
            }
    
            update safeListForChunking;
        }
    }