[SalesForce] how to write trigger for update child field with parent field

My scenario is: Employee is child object and contact is parent object. Both have the same field test__c. When we update or insert employee object, test__c field value is equal to any contact record particular contact and field value updates to employee field. If no contact is there no need to update this field. My code:

trigger fillValueInChild on Employee__c (before insert, before update) {

    list<employee__c> employ = new list<employee__c>();

    for(employee__c emp : trigger.new){

        list<contact> con = [select id,test__c from contact where test__c =:emp.test__c limit 1];
        if(con.size()>0){
            for(contact c : con){
                for(employee__c e: trigger.new){
                    e.test__c = c.test__C;
                    e.contact__c = c.id;
                    employ.add(e);
                }
            }
        }
        else if(con.isempty()){
            emp.test__c = null;
            employ.add(emp);
        }
    }
    update employ;
}

I'm getting this error

Error: Invalid Data. Review all error messages below to correct your
data. Apex trigger fillValueInChild caused an unexpected exception,
contact your administrator: fillValueInChild: execution of
BeforeUpdate caused by: System.SObjectException: DML statement cannot
operate on trigger.new or trigger.old: Trigger.fillValueInChild: line
22, column 1

Best Answer

Your code was a bit confusing but if I understood correctly you wanted to get all contacts that have the test__c value and apply those values to the tmp record. If no contacts are found then you want to apply null values...

  1. Since this is a before trigger no need to do any DML. Changes you make to the tmp record will be persisted to the database
  2. get the query outside of the loop

    trigger fillValueInChild on Employee__c (before insert, before update) {
    
        list<employee__c> employ = new list<employee__c>();
    
        //Collection of test__c values to look for
        Set<String> valToCheck = Set<String>();
        //I did not do a list of contacts here as your question had a limit 1 in the query
        Map<String,Contact> valsFound = New Map<String,Contact>();
    
        for(employee__c emp : trigger.new){
            if(!string.isBlank(emp.test__c)) valToCheck.add(emp.test__c);
        }
    
        for(Contact c : [select test__c from contact where test__c IN :valToCheck ]){
            valsFound.put(c.test__c,c);
        }
    
        for(employee__c emp : trigger.new){
    
            if(valsFound.containsKey(emp.test__c)){
                emp.contact__c = valsFound.get(emp.test__c).id;
            }else{
                emp.test__c = null;
            }
        }
    }
    
Related Topic