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
Mthobisi NdlovuMthobisi Ndlovu 

Trigger to delete Account Record when Contact record gets deleted

I have a trigger that has to delete an Account record associated with a Contact record when that particular contact  record gets deleted, However I get the following error when the DML  statement delete get's executed.

"15:14:59:227 FATAL_ERROR System.DmlException: Delete failed. First exception on row 0 with id 0011100000R5Gf0AAF; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 0031100000QId7U) is currently in trigger deleteAccountRecord, therefore it cannot recursively delete itself: []"

here is my code: 

trigger deleteAccountRecord on Contact (before delete) {


    RecordType donorRecType = [SELECT ID FROM RecordType WHERE sObjectType = 'Contact' AND DeveloperName = 'Donor_Contact'];
    if(Trigger.isDelete){
        List<ID> contactIDList = new List<ID>();
        for(Contact contactToDelete: Trigger.old) {
            if (contactToDelete.RecordTypeId != donorRecType.Id ) {
                  
                    contactIDList.add(contactToDelete.id);
            }
        }
      
       
       List<Account> DelAccountRecordList = [select id from Account where Id IN(SELECT accountId FROM Contact WHERE Id IN :contactIDList)];

        if(DelAccountRecordList.size() >0 && RecursiveTriggerHelper.isFirstRun){
           RecursiveTriggerHelper.isFirstRun = false;
           delete DelAccountRecordList ;
         
        }
     }
  }

//Helps to stop the trigger from firing twice. (at least It should but it's not working)
public class RecursiveTriggerHelper {

     public static boolean isFirstRun = true;
  
}

I have tried using "After Insert" but DelAccountRecordList returns null with no records. Is there a way to deal with my error without changing "Before Update". I am totally out of ideas on how to solve this issue.

Thanks in advance for your help.
Best Answer chosen by Mthobisi Ndlovu
Vinit_KumarVinit_Kumar
Ok got your point,then you don't need a before Trigger and helpre Class.Try below code this should work :-

trigger deleteAccountRecord on Contact (after delete) {


    RecordType donorRecType = [SELECT ID FROM RecordType WHERE sObjectType = 'Contact' AND DeveloperName = 'Donor_Contact'];
    if(Trigger.isDelete){
        List<ID> accIds = new List<ID>();
        for(Contact contactToDelete: Trigger.old) {
            if (contactToDelete.RecordTypeId != donorRecType.Id ) {
                  
                    contactIDList.add(contactToDelete.AccountId);
            }
        }
      
       
       List<Account> DelAccountRecordList = [select id from Account where Id IN:accIds];

        if(DelAccountRecordList.size() >0){
           delete DelAccountRecordList ;
         
        }
     }
  }

If this helps,please mark this as best answer to help others :)

All Answers

Vinit_KumarVinit_Kumar
This is happening because when you Delete the Account, through trigger ,it is trying to delete the related Contacts as well as per standard Functionality of salesforce.

As you are deleting the Contact through UI,it is throwing error. 

Also,I don't understand the use case here.

Account and contact has one to many relationship.As per your logic,if you delete one Contact it would relate the Account which is subsequently going to delete all the Contacts with that Account(standard functionality) which means you have lost Contact data.

Can you pls explain what is the use case here ??
Mthobisi NdlovuMthobisi Ndlovu
Hey Vinit

Thanks for the reply.

Basically it's like this... I have a trigger that creates an Account when ever a Contact is created, so the relationship is more like 1:1, the reason for this is to make sharing rules on the Contact object work because if a Contact record is not associated with an Account it becomes a private record and sharing rules become meaningless.

The Users who will be working with the contacts (have a seperate record type) do not have access to Account object. So the reason for this trigger is to delete the Account record associated with the contact record being deleted without having to go to the Account object. I hope you understand what I am saying.

Is there a work around to what you mentioned above?

Vinit_KumarVinit_Kumar
Ok got your point,then you don't need a before Trigger and helpre Class.Try below code this should work :-

trigger deleteAccountRecord on Contact (after delete) {


    RecordType donorRecType = [SELECT ID FROM RecordType WHERE sObjectType = 'Contact' AND DeveloperName = 'Donor_Contact'];
    if(Trigger.isDelete){
        List<ID> accIds = new List<ID>();
        for(Contact contactToDelete: Trigger.old) {
            if (contactToDelete.RecordTypeId != donorRecType.Id ) {
                  
                    contactIDList.add(contactToDelete.AccountId);
            }
        }
      
       
       List<Account> DelAccountRecordList = [select id from Account where Id IN:accIds];

        if(DelAccountRecordList.size() >0){
           delete DelAccountRecordList ;
         
        }
     }
  }

If this helps,please mark this as best answer to help others :)
This was selected as the best answer
Mthobisi NdlovuMthobisi Ndlovu

Thanks a lot Vinit it works, I had tried using "After Delete" but I see where my mistake was. I need to do a lot of reading up on the triggers this was my second trigger.

line 10 should be:

accIds.add(contactToDelete.accountId);

Vinit_KumarVinit_Kumar
Yes that was a typo :)
Abhi MalikAbhi Malik
HI Mthobisi Ndlovu

Can you please share the code for this problem am also trying this kind of problem.

Thanks & Regards
Abhi malik
Anish Kumar 70Anish Kumar 70
<apex:page controller="ActionTableCheck" showHeader="false" >
<head>


<apex:stylesheet value="{!URLFOR($Resource.slds, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />


<!-- Import the Design System style sheet -->
<apex:slds />

</head>
<div class="slds-scope" >
<apex:form >
                        
    <apex:actionFunction name="isChecked" action="{!isChecked}"  />
     <apex:actionFunction name="next" action="{!next}" />
    <apex:actionFunction name="first" action="{!first}"/>
    <apex:actionFunction name="previous" action="{!previous}"/>
    <apex:actionFunction name="last" action="{!last}"/>
        <apex:pageBlock id="refreshpage1">
        <apex:pageblockButtons >
        <apex:outputPanel id="myButtons">
         <div class="slds-button-group " role="group">
            <apex:commandButton value="Save & Update" action="{!Save}" styleClass="slds-button slds-button--neutral "/>
            <apex:commandButton value="Beginning" styleClass="slds-button slds-button--neutral " onclick="first();  return false;" disabled="{!disabledPrevious}" />
            <apex:commandButton value="Previous" onclick="previous(); return false;" disabled="{!disabledPrevious}" styleClass="slds-button slds-button--neutral "/>
            <apex:commandButton value="Next" onclick="next(); return false;" disabled="{!disabledNext}" styleClass="slds-button slds-button--neutral "/>
            
            <apex:commandButton value="End" onclick="last(); return false;" disabled="{!disabledNext}" styleClass="slds-button slds-button--neutral " />
            
         <apex:commandButton value="Add Row" action="{!AddRow}" styleClass="slds-button slds-button--neutral " />
         <apex:commandButton value="Delete Row" action="{!DeleteRow}" styleClass="slds-button slds-button--neutral " />
         </div>
        </apex:outputPanel>
         </apex:pageblockButtons>
            <apex:outputPanel >
                
                 <apex:dataTable value="{!WrapperCheck}" var="c" styleClass="slds-table slds-table--bordered slds-table--striped">
                   <apex:column >
                       <apex:facet name="header">
                      <apex:inputCheckbox value="{!AllChecked}">
                       
                          <apex:actionSupport event="onclick" action="{!checkAll}" rerender="refreshpage1"/> </apex:inputCheckbox>
                      
                       </apex:facet>
                        <apex:inputCheckbox value="{!c.isChecked}" onclick="isChecked()" />
                    </apex:column>
                    
                    <apex:column headerValue="First Name"  >
                        <apex:outputField value="{!c.cont.firstname}" rendered="{!NOT(c.EditContact)}"/>
                        <apex:inputField value="{!c.cont.firstname}" rendered="{!c.editContact}"/>
                        
                    </apex:column>
                    
                    <apex:column headerValue="Last Name">
                        <apex:outputField value="{!c.cont.lastname}" rendered="{!NOT(c.EditContact)}"/>
                        <apex:inputField value="{!c.cont.lastname}" rendered="{!c.editContact}"/>
                    </apex:column>
                    
                    <apex:column headerValue="Email">
                        <apex:outputField value="{!c.cont.email}" rendered="{!NOT(c.EditContact)}"/>
                        <apex:inputField value="{!c.cont.email}" rendered="{!c.editContact}"/>
                    </apex:column>
                                                        
                    <apex:column headerValue="PhoneNo">
                        <apex:outputField value="{!c.cont.phone}" rendered="{!NOT(c.EditContact)}"/>
                        <apex:inputField value="{!c.cont.phone}" rendered="{!c.editContact}"/>
                    </apex:column>        
                </apex:datatable>
                
            </apex:outputPanel>
           <apex:pageBlockButtons >
            
        </apex:pageBlockButtons> 
        </apex:pageBlock>
    </apex:form>
    </div>
</apex:page>

How  to apply slds class in apex:column headervalue.Please help me.
Abdulla d 5Abdulla d 5
i am getting following error, can you please solve it

Trigger name, Contact_example1, exists on different SObject type: Contract