function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ben HuriBen Huri 

Delete related list.

Hey guys, what is your best suggested way to delete a record with it's related lists and it's look up fields??

I thought to query all records with SOSL by the record Id, but i found out it is not possible (Or there's a way?).

Another option is quering all related lists (with inner loops) and then loop on all related lists (with getPopulatedFieldsAsMap() and delete them list by list.

I would love to hear your best solution in performence terms.

Thanks!
 
Best Answer chosen by Ben Huri
Suraj Tripathi 47Suraj Tripathi 47
Hi Ben,
Greetings!

Please write a trigger for Before Delete.
Fetch all the child records in the inner query.
But please use batch class and create a chunk of a single record to avoid the governor limits.

If you find your Solution then mark this as the best answer. 

Thank you!

Regards,
Suraj Tripathi

All Answers

Suraj Tripathi 47Suraj Tripathi 47
Hi Ben,
Greetings!

Please write a trigger for Before Delete.
Fetch all the child records in the inner query.
But please use batch class and create a chunk of a single record to avoid the governor limits.

If you find your Solution then mark this as the best answer. 

Thank you!

Regards,
Suraj Tripathi
This was selected as the best answer
Ben HuriBen Huri

Hi Suraj,
Thanks for your answer.
Yeah i thought to use a batch class, but wasn't sure if it would be better retrieve data by SOSL somehow, or just by fetching all child records.

Thanks!

Suraj Tripathi 47Suraj Tripathi 47
Hi Ben,
You don't need to perform a SOSL.
You will implement this easily by SOQL.

If you find your Solution then mark this as the best answer. 
Ben HuriBen Huri
Ok :)
So after I'm fetching all related lists in the batch's start method - should I loop on each list (list of single type) and delete them one by one?
Isn't it over performence?

Or do you generally recommend to create a single batch for each record and fetch all records before the batch creation?
Again, i want to reduce performence as much as i can.
 
mukesh guptamukesh gupta
Hi Ben,

Yes it is possible, we can call a batch apex from trigger but we should always keep in mind that we should not call batch apex from trigger each time as this will exceeds the governor limit this is because of the reason that we can only have 5 apex jobs queued or executing at a time.

Please follow below example code:-
 
trigger maintrigger on Account(before delete) {
 
  Set<id> accList = new Set<Id>();
    for(Account acc :trigger.old){
          accList.add(acc.id);
    }
    if(accList.size() > 0){
   
  List<contact> conList = [select id from contact where AccountId =: accList];

        database.executeBatch(new DeleteRelatedContacts(conList )); // Calling batch class.
    }

}

DeleteRelatedContacts:-
 
global class MailToNewContact implements Database.Batchable<sObject>
{
   Set<Id> conListBacth =new Set<id>();
    global MailToNewContact(Map<id,contact> IdContactMap){
        conListBacth =conList;
    }
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        return Database.getQueryLocator([SELECT id from contact where id in:conListBacth]);
    }
    global void execute(Database.BatchableContext BC, List<Contact> contctList) {     
     
// Delete the contacts
Database.DeleteResult[] drList = Database.delete(contctList, false);

// Iterate through each returned result
for(Database.DeleteResult dr : drList) {
    if (dr.isSuccess()) {
        // Operation was successful, so get the ID of the record that was processed
        System.debug('Successfully deleted account with ID: ' + dr.getId());
    }
    else {
        // Operation failed, so get all errors                
        for(Database.Error err : dr.getErrors()) {
            System.debug('The following error has occurred.');                    
            System.debug(err.getStatusCode() + ': ' + err.getMessage());
        }
  
}
        }
    }
    global void finish(Database.BatchableContext BC)
    {
    }
}
if you need any assistanse, Please let me know!!

Kindly mark my solution as the best answer if it helps you.

Thanks
Mukesh 

 
Suraj Tripathi 47Suraj Tripathi 47
Hi Ben,

In the start method, fetch all the related lists.
For example,
SELECT Id, (SELECT Id FROM Contacts), (SELECT Id FROM Opportunities) FROM Account WHERE Id IN :trigger.new;

In execute,
Perform a DML Like
if(!accList.Contacts.isEmpty)
    DELETE accList.Contacts;
if(!accList.Opportunities.isEmpty)
    DELETE accList.Opportunities;

Execute this batch creating chunks of a single record.
Like-
Database.executeBatch(new ClassName(), 1);
Thanks