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
HARSHIL U PARIKHHARSHIL U PARIKH 

Trigger works fine for individual record entry but when mass updated, all records gets updated with same value.

Hello Developers!
I need some help on this..
Two Objects with Master-Detail: 1) Volunteer_Project__c (Master) , 2) Participation__c (Detail)
Task: Need to count identical email address on parent for child.
Trigger:
Trigger UniqueEmailCount On Volunteer_Project__c(before insert, before update)
{
    List<Participation__c> ParticipationList = new List<Participation__c>();
    Set<String> uniqueEmails = new Set<String>();
    
    
    ParticipationList = [SELECT Volunteer_Email__c FROM Participation__c where Volunteer_Project_Name__c IN :Trigger.New];

        for (Integer i = 0; i< ParticipationList.size(); i++)
        {uniqueEmails.add(ParticipationList[i].Volunteer_Email__c);
        }
        
        for(Volunteer_Project__c proj: Trigger.new)
        { 
        proj.Total_Associated_Volunteers__c = uniqueEmails.size();
        }
}
Problem:
When I individually add parent and then child for them it counts unique emails. All good as of now!
But when I Mass update all parent then they all gets updated with same value.
(e.g., Let's say 3 projects A, B, C and each has Total_Associated_Volunteers__c as 5, 10, 15.
But When I update all 3 project as Mass Update then all Projects has Total_Associated_Volunteers__c = 15)
Thank you for the support!
 
Best Answer chosen by HARSHIL U PARIKH
Santosh Sriram 2310Santosh Sriram 2310
trigger UniqueEmailCount On Volunteer_Project__c(before update)
{
    List<Participation__c> ParticipationList = new List<Participation__c>();
    Set<String> uniqueEmails = new Set<String>();
    
    //Creating the selection to have project wise participation's email
    map<Id,set<String>> map_projectToParticipation  = new map<Id,set<String>>();

    //Iterating through the list of volunteer project
    for(Participation__c iterating_participation : [SELECT Volunteer_Project_Name__c,Volunteer_Email__c FROM Participation__c where Volunteer_Project_Name__c IN :Trigger.New]){
        //checking if existing
        if(map_projectToParticipation.containsKey(iterating_participation.Volunteer_Project_Name__c)){
            //Getting the existing participation set
            set<String> listParticipation = map_projectToParticipation.get(iterating_participation.Volunteer_Project_Name__c);
            listParticipation.add(iterating_participation.Volunteer_Email__c);
            map_projectToParticipation.put(iterating_participation.Volunteer_Project_Name__c, listParticipation);
        }else{
             //Getting the existing participation set
            set<String> listParticipation = new set<String>();
            listParticipation.add(iterating_participation.Volunteer_Email__c);
            map_projectToParticipation.put(iterating_participation.Volunteer_Project_Name__c, listParticipation);
        }
    }
    //Final looping to get set size
    for(Volunteer_Project__c proj: Trigger.new){ 
        if(map_projectToParticipation.containsKey(proj.Id))
            proj.Total_Associated_Volunteers__c = map_projectToParticipation.get(proj.id).size();
    }
}

 

All Answers

Santosh Sriram 2310Santosh Sriram 2310
Hi Govind

So here is the thing. You cannot have a before insert on the trigger. It does not make any sense, as it will not have children associated to the parent by then. 
I have changed the looping logic of your base trigger for it to work for your needs.
 
trigger UniqueEmailCount On Volunteer_Project__c(before update)
{
    List<Participation__c> ParticipationList = new List<Participation__c>();
    Set<String> uniqueEmails = new Set<String>();
    
    //Creating the selection to have project wise participation's email
    map<Id,set<String>> map_projectToParticipation  = new map<Id,set<String>>();

    //Iterating through the list of volunteer project
    for(Participation__c iterating_participation : [SELECT Volunteer_Email__c FROM Participation__c where Volunteer_Project_Name__c IN :Trigger.New]){
        //checking if existing
        if(map_projectToParticipation.containsKey(iterating_participation.Volunteer_Project_Name__c)){
            //Getting the existing participation set
            set<Participation__c> listParticipation = map_projectToParticipation.get(iterating_participation.Volunteer_Project_Name__c);
            listParticipation.add(iterating_participation.Volunteer_Email__c);
            map_projectToParticipation.put(iterating_participation.Volunteer_Project_Name__c, listParticipation);
        }else{
             //Getting the existing participation set
            set<Participation__c> listParticipation = new set<Participation__c>();
            listParticipation.add(iterating_participation.Volunteer_Email__c);
            map_projectToParticipation.put(iterating_participation.Volunteer_Project_Name__c, listParticipation);
        }
    }
    //Final looping to get set size
    for(Volunteer_Project__c proj: Trigger.new){ 
        if(map_projectToParticipation.containsKey(proj.Id))
            proj.Total_Associated_Volunteers__c = map_projectToParticipation.get(proj.id).size();
    }
}

If it helps, mark this as an answer! Thanks a lot!
HARSHIL U PARIKHHARSHIL U PARIKH
Hi Thank you for follow up..I appreciate it!
I am try to execute and it says:
Error: Compile Error: Illegal assignment from Set<String> to Set<Participation__c> at line 14 column 35
HARSHIL U PARIKHHARSHIL U PARIKH
Trigger saves without an error;) But when I update existing parent record then beow is the error shown:

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger UniqueEmailCount caused an unexpected exception, contact your administrator: UniqueEmailCount: execution of BeforeUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Participation__c.Volunteer_Project_Name__c: Trigger.UniqueEmailCount: line 12, column 1

When I Enter new child record then below is the error shown:

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger UniqueEmailCount caused an unexpected exception, contact your administrator: UniqueEmailCount: execution of BeforeUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Participation__c.Volunteer_Project_Name__c: Trigger.UniqueEmailCount: line 12, column 1

 
Santosh Sriram 2310Santosh Sriram 2310
trigger UniqueEmailCount On Volunteer_Project__c(before update)
{
    List<Participation__c> ParticipationList = new List<Participation__c>();
    Set<String> uniqueEmails = new Set<String>();
    
    //Creating the selection to have project wise participation's email
    map<Id,set<String>> map_projectToParticipation  = new map<Id,set<String>>();

    //Iterating through the list of volunteer project
    for(Participation__c iterating_participation : [SELECT Volunteer_Project_Name__c,Volunteer_Email__c FROM Participation__c where Volunteer_Project_Name__c IN :Trigger.New]){
        //checking if existing
        if(map_projectToParticipation.containsKey(iterating_participation.Volunteer_Project_Name__c)){
            //Getting the existing participation set
            set<String> listParticipation = map_projectToParticipation.get(iterating_participation.Volunteer_Project_Name__c);
            listParticipation.add(iterating_participation.Volunteer_Email__c);
            map_projectToParticipation.put(iterating_participation.Volunteer_Project_Name__c, listParticipation);
        }else{
             //Getting the existing participation set
            set<String> listParticipation = new set<String>();
            listParticipation.add(iterating_participation.Volunteer_Email__c);
            map_projectToParticipation.put(iterating_participation.Volunteer_Project_Name__c, listParticipation);
        }
    }
    //Final looping to get set size
    for(Volunteer_Project__c proj: Trigger.new){ 
        if(map_projectToParticipation.containsKey(proj.Id))
            proj.Total_Associated_Volunteers__c = map_projectToParticipation.get(proj.id).size();
    }
}

 
This was selected as the best answer