Fondo

Tengo una lista de sObjects que necesito insertar, pero primero debo verificar si la inserción será exitosa. Entonces, estoy configurando un punto de guardado de la base de datos antes de realizar la inserción y verificar los resultados de guardado (para la declaración de inserción). Porque, no quiero procesar si ocurrió algún error, si hubo algún error en los resultados de la inserción, la base de datos se revierte al punto de guardado.

Problema y pregunta

Necesito recopilar los errores para cada resultado guardado (insertar) y asociar cada error al registro sObject específico que causó el error. Según la documentación Guardar resultados contienen una lista de errores, el ID de Salesforce del registro insertado (si tiene éxito) y un indicador de éxito (booleano).

¿Cómo asocio el resultado guardado al registro de sObject original insertado?

Código / Ejemplo

Aquí hay un ejemplo que reuní que demuestra el concepto. El ejemplo es defectuoso, ya que el InsertResults no siempre coincide con el sObjectsToInsert. No es exactamente el código que estoy usando en mi clase personalizada, pero usa la misma lógica.

Map<Id,sObject> sObjectsToInsert; // this variable is set previously in the code
List<Database.SaveResult> InsertResults;

Map<String,sObject> ErrorMessages = new Map<String,sObject>();

System.SavePoint sp = Database.setSavepoint();

// 2nd parameter must be false to get all errors, if there are errors
//   (allow partial successes)
InsertResults = Database.insert(sObjectsToInsert.values(), false); 

for(Integer i=0; i < InsertResults.size(); i++)
{
  // This method does not guarantee the save result (ir) matches the sObject
  //   I need to make sure the insert result matches
  Database.SaveResult ir = InsertResults[i];
  sObject s = sObjectsToInsert.values()[i]; 

  String em = null; // error message
  Integer e = 0; // errors

  if(!ir.isSuccess())
  {
    system.debug('Not Successful');
    e++;

    for(Database.Error dbe : ir.getErrors()) { em += dbe.getMessage()+' '; }
    ErrorMessages.put(em, s);
  }
}

if(e > 0)
{
  database.rollback(sp);

  // log all errors in the ErrorMessages Map
}
2
Matt K 6 jun. 2012 a las 18:08

1 respuesta

La mejor respuesta

Su comentario dice que no se garantiza que la lista SaveResult esté en orden, pero creo que sí. He usado esta técnica durante años y nunca he tenido ningún problema.

5
Jeremy Ross 6 jun. 2012 a las 18:23
Yo también lo pensé (+1 por eso), pero tengo un problema inexplicable para emparejarlos, y estoy bastante seguro de que no coinciden.
 – 
Matt K
6 jun. 2012 a las 18:36
Después de recopilar los errores, trato de insertar los registros que habrían tenido éxito, pero cuando intento insertar los registros que se han realizado correctamente, obtengo el mismo error que se detectó anteriormente. En este caso particular, tengo 6 registros que estoy tratando de insertar, 3 exitosos, 3 errores. Intento insertar el 3 que tendría éxito y recibo el mismo error registrado en el 3 que se produjo anteriormente. Supongo que es posible que estén en el orden correcto, pero no sé de qué otra manera explicar lo que estoy viendo.
 – 
Matt K
6 jun. 2012 a las 18:50
Si estoy insertando valores de mapa (Database.insert(sObjectsToInsert.values(), false);), ¿eso provocaría que los valores no coincidan?
 – 
Matt K
6 jun. 2012 a las 19:35
1
Sí ... el mapa no garantiza el orden.
 – 
Jeremy Ross
6 jun. 2012 a las 21:51