5

I saw an example how to insert Parent and Child Record in one DML Statement from Developer Guide and It's Working Fine no issue in that.

Here In my case I would like insert List Of Both Parent and Child Record in one dml statement.

I have written the code but the issue is it's inserting only parent record child record is not inserted.

public class ParentChildSample {
    public static void InsertParentChild() {
        Date dt = Date.today();
        dt = dt.addDays(7);
        List<Opportunity> opp = new List<Opportunity>();
        List<Account> acc = new List<Account>();

        for(Integer i = 0; i < 3; i++){

            Opportunity newOpportunity = new Opportunity(Name='OpportunityWithAccountInsert ' +i,StageName='Prospecting',CloseDate=dt);        
            Account accountReference = new Account(MyExtID__c='SAP111111'+i); 
            newOpportunity.Account = accountReference;
            Account parentAccount = new Account(Name='Hallie '+i);
            system.debug('DDDDDDDDDDDDDDDDDD'+newOpportunity.Account);
            opp.add(newOpportunity);
            acc.add(parentAccount);


        }




        Database.SaveResult[] results = Database.insert(acc,opp);


        for (Integer i = 0; i < results.size(); i++) {
            if (results[i].isSuccess()) {
                System.debug('Successfully created ID: '+ results[i].getId());
            } else {
                System.debug('Error: could not create sobject '+ 'for array element ' + i + '.');
                System.debug(' The error reported was: '+ results[i].getErrors()[0].getMessage() + '\n');
            }
        }
    }
}

In Developer guide they are using this particular line

Database.SaveResult[] results = Database.insert(new SObject[] {parentAccount, newOpportunity });

But that is for Single record so I'm Using the below line to Insert List of Parent and Child Record

Database.SaveResult[] results = Database.insert(acc,opp);
  • why aren't you following the developer guide and inserting a list of SObjects? What parameters can you pass into the Database.insert() method? – Nick Cook Aug 1 '16 at 10:47
6

In the doc, the example given is a list of two sobjects:

Database.SaveResult[] results = Database.insert(new SObject[] {parentAccount, newOpportunity });

If you want to do a list of lists:

SObject[] sobjList = new List<SObject>();
sobjList.addAll(acc);
sobjList.addAll(opp);
Database.SaveResult[] results = Database.insert(sobjList);

As an aside, acc and opp should really be plural names if they are to represent lists.

3

I create a test class as below

@isTest
public class test{
    public static testMethod void method1(){
        Account a1 = new Account(Name = 'test1');
        insert a1;
        Account a2 = new Account(Name = 'test2');
        Account a3 = new Account(Name = 'test3');
        List<Account> lstAccount = new List<Account>{a2,a3};
        contact c1 = new Contact(LastName = 'c1',accountId = a1.Id);
        contact c2 = new Contact(LastName = 'c2',accountId = a1.Id);
        List<Contact> lstContact = new List<Contact>{c1,c2};
        System.Test.startTest();
        //Database.SaveResult[] results = Database.insert(new SObject[] {a2,a3,c1,c2});
        Database.SaveResult[] results = Database.insert(lstAccount,lstContact);
        System.Test.stopTest();
        system.assertEquals(3,[select count() from account]);
        system.assertEquals(2,[select count() from contact]);
    }
}

When i use just like how it is shown in Developer blog(using new SObject[]()), the assertion pass.

But when i used like your scenario (directly using list of Account, list of contact), the assertion fail as no contacts are inserted.

  1. In first, the account and contacts are type cast to SObject and assigned to the list of SObject and inserted as SObjects and later cast back to its original Objects (account, contact) internally by salesforce.
  2. In second, the lstContact is completely omitted and only lstAccount is inserted. But am really not sure why it didn't throw any syntax error as there is no method insert(List<SObject>,List<SObject>) is present in Database class.

I think it deserves a separate question.

2

For Multiple records you can use the same method signature. I used following line of code in anonymous window and it worked Fine

Date dt = Date.today();
dt = dt.addDays(7);

List<sObject> lstSobject = new List<sObject>();

Opportunity newOpportunity1 = new Opportunity(Name='OpportunityWithAccountInsert1',StageName='Prospecting',CloseDate=dt);        
Account accountReference = new Account(MyExtID__c='12345'); 
newOpportunity1.Account = accountReference;
lstSobject.add(newOpportunity1);

Opportunity newOpportunity2 = new Opportunity(Name='OpportunityWithAccountInsert2',StageName='Prospecting',CloseDate=dt);        
Account accountReference = new Account(MyExtID__c='12345'); 
newOpportunity2.Account = accountReference;
lstSobject.add(newOpportunity2);

Account parentAccount1 = new Account(Name='Hallie',MyExtID__c='SAP1111112'); 
lstSobject.add(parentAccount1);
Account parentAccount2 = new Account(Name='Hallie',MyExtID__c='SAP111111'); 
lstSobject.add(parentAccount2);

Database.SaveResult[] results = Database.insert(lstSobject);

for (Integer i = 0; i < results.size(); i++) {
            if (results[i].isSuccess()) {
            System.debug('Successfully created ID: '
                  + results[i].getId());
            } else {
            System.debug('Error: could not create sobject '
                  + 'for array element ' + i + '.');
            System.debug('   The error reported was: '
                  + results[i].getErrors()[0].getMessage() + '\n');
            }
        }

It created 2 Account records and 2 Child opportunity records referring to same parent account.You will get Ids of all inserted records in debug.

I found the documentation little misleading. It states that

The example creates an Opportunity sObject and populates some of its fields, then creates two Account objects. The first account is only for the foreign key relationship, and the second is for the account creation and has the account fields set.

However the account used for foreign key relationship of opportunity already exist in DB with same external Id field specified. So actually only one Account record is created not two.

  • Good work on providing an example that anyone can use in an execute anonymous window. – Nick Cook Aug 2 '16 at 12:22
  • @Nick and yet you didn't vote for it! – Adrian Larson Aug 2 '16 at 12:54
  • @AdrianLarson In my defence, I didn't take the time to work out if it was a good answer :) – Nick Cook Aug 2 '16 at 12:58
  • @Monalisa Thank you for your answer..! I just Copy pasted your code but I'm facing this error " Insert failed. First exception on row 0; first error: INVALID_FIELD, Foreign key external ID: 12345 not found for field MyExtID__c in entity Account: [] " – Sharat Aug 3 '16 at 5:13
  • @Sharat - You need to create record in your org with the same external Id value. This error simply suggest you don't have any record in Account with this value in external Id field – Monalisa Das Aug 4 '16 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.