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
Tim AndrewsTim Andrews 

Need help with a cross-object Apex trigger

Hello all,

I am new to writing Apex triggers and am hung up on some practice I am working on. In my dev org, I have created two custom objects (Alpha__c and Beta__c). I am attempting to write a trigger that populates a lookup field on Beta__c called Beta_Apex_Test_Field_1__c with the data from the Alpha__c object field called Alpha_Test_Field_1__c. The update should trigger when the Alpha__c object record is updated to populate this field.

I've attempted to use code modified from other examples, but I'm getting stuck and the trigger doesn't fire or throw any exceptions. Below is the code I've written. Can someone help a struggling newbie developer?

// Attempting to update a lookup field on the Beta__c custom object called Beta_Apex_Test_Field_1__c with the value that is input into the Alpha__c custom 
// object field called Alpha_Test_Field_1__c. 

trigger SyncAlphaToBeta on Alpha__c (after update) {
    
    Set<String> fieldupdates = new Set<String>();
    for(Alpha__c a : Trigger.new) {
        if(a.Alpha_Test_Field_1__c != null) fieldupdates.add(a.Alpha_Test_Field_1__c);
    }
    
    Map<String, Beta__c> betas = new Map<String, Beta__c>();
    for(Beta__c b : [SELECT Id, Name, Beta_Apex_Test_Field_1__c FROM Beta__c WHERE Name IN :fieldupdates]) {
        betas.put(b.Name, b);
        
    }
              
    for(Alpha__c a : Trigger.new) {
        if(a.Alpha_Test_Field_1__c != null) {
            if(betas.containsKey(a.Alpha_Test_Field_1__c)) {
                a.Alpha_Test_Field_1__c = betas.get(a.Alpha_Test_Field_1__c).Id;
            }
        }
    }
}
Best Answer chosen by Tim Andrews
Neetu_BansalNeetu_Bansal
Hi Tim,

When you already have Related_Alpha__c for relation, then why are you creating one more look up of Alpha on Beta? I guess in Beta_Apex_Test_Field_1__c you want to copy the value of Alpha_Test_Field_1__c. If yes, you can just create a formula field for this, using the Related_Alpha__c. If there is some specific reasons, use the below code:
// Attempting to update a lookup field on the Beta__c custom object called Beta_Apex_Test_Field_1__c with the value that is input into the Alpha__c custom object field called Alpha_Test_Field_1__c. 
trigger SyncAlphaToBeta on Alpha__c( after update )
{
	Set<String> fieldupdates = new Set<String>();
    for( Alpha__c a : Trigger.new )
	{
        if( a.Alpha_Test_Field_1__c != null 
			&& a.Alpha_Test_Field_1__c != trigger.oldMap.get( a.Id ).Alpha_Test_Field_1__c )
		{
			fieldupdates.add(a.Alpha_Test_Field_1__c);
		}
    }
    
    Map<Id, Beta__c> betas = new Map<String, Beta__c>();
    for( Beta__c b : [ SELECT Id, Name, Beta_Apex_Test_Field_1__c, Related_Alpha__c FROM Beta__c WHERE Name IN :fieldupdates ])
	{
        betas.put( b.Related_Alpha__c, b );
    }
          
    for( Alpha__c a : Trigger.new )
	{
        if( a.Alpha_Test_Field_1__c != null 
			&& a.Alpha_Test_Field_1__c != trigger.oldMap.get( a.Id ).Alpha_Test_Field_1__c )
		{
            if( betas.containsKey(a.Id) )
			{
                betas.get( a.Id ).Beta_Apex_Test_Field_1__c = a.Id;
            }
        }
    }
	
	if( betas.size() > 0 )
		update betas.values();
}
Let me know, if you need any other help. You can also contact me on my personal id i.e. Gmail id: neetu.bansal.5@gmail.com or Skype id: neetu.bansal.5

Thanks,
Neetu

All Answers

JeffreyStevensJeffreyStevens
Tim,  if your Beta_Apex_Test_Field_1__c  field is really a lookup type field to object Alpha__c, then the contents of that field will be a Salesforce ID (The record ID of the Alpha__c record).  If that is the case - then your SOQL is wrong.  It's using the list of strings of fieldUpdates - but you're populating that list of the Alpha_Test_Field_1__c field - it should be populated with the ID of the Alpha__c record.

Can you check for us and let us know the definition of the Beta_Apex_Test_Field_1__c field?
Tim AndrewsTim Andrews
Thanks for reaching out, @JeffreyStevens. The Beta_Apex_Test_Field_1__c field is truly a lookup field to the Alpha__c object. Any help you can provide with changing the code to accomplish populating this field (and with my amateur code, in general) would be greatly appreciated. This is a warm-up exercise for some real-world work I need to do. -Tim
Ketankumar PatelKetankumar Patel

Hi Tim couple of questions
1) Beta_Apex_Test_Field_1__c is lookup field to Alpha__c object?
2) Is Alpha_Test_Field_1__c is a lookup field too? or Text?
Neetu_BansalNeetu_Bansal
Hi Tim,

The below trigger will works if the Name field of Beta is equal to the value of Alpha_Test_Field_1__c of Alpha.
// Attempting to update a lookup field on the Beta__c custom object called Beta_Apex_Test_Field_1__c with the value that is input into the Alpha__c custom object field called Alpha_Test_Field_1__c. 
trigger SyncAlphaToBeta on Alpha__c( after update )
{
	Set<String> fieldupdates = new Set<String>();
    for( Alpha__c a : Trigger.new )
	{
        if( a.Alpha_Test_Field_1__c != null 
			&& a.Alpha_Test_Field_1__c != trigger.oldMap.get( a.Id ).Alpha_Test_Field_1__c )
		{
			fieldupdates.add(a.Alpha_Test_Field_1__c);
		}
    }
    
    Map<String, Beta__c> betas = new Map<String, Beta__c>();
    for( Beta__c b : [ SELECT Id, Name, Beta_Apex_Test_Field_1__c FROM Beta__c WHERE Name IN :fieldupdates ])
	{
        betas.put( b.Name, b );
    }
          
    for( Alpha__c a : Trigger.new )
	{
        if( a.Alpha_Test_Field_1__c != null 
			&& a.Alpha_Test_Field_1__c != trigger.oldMap.get( a.Id ).Alpha_Test_Field_1__c )
		{
            if( betas.containsKey(a.Alpha_Test_Field_1__c) )
			{
                betas.get( a.Alpha_Test_Field_1__c ).Beta_Apex_Test_Field_1__c = a.Id;
            }
        }
    }
	
	if( betas.size() > 0 )
		update betas.values();
}
Let me know, if you need any other help.

Thanks,
Neetu
Tim AndrewsTim Andrews
Hello @Ketankumar Patel,

1) Beta_Apex_Test_Field_1__c is lookup field to Alpha__c object? - Yes, this is correct.
2) Is Alpha_Test_Field_1__c is a lookup field too? or Text? This is a text field.

Thank you for your help!
Tim
 
Tim AndrewsTim Andrews
@Neetu_Bansal, thank you for your help. How could we make this work if the Name field of Beta is NOT equal to the value of Alpha_Test_Field_1__c of Alpha? There is another lookup field between these obejcts that links them together - Beta__c looks up to Alpha__c via a field on Beta__c called Related_Alpha__c, which links the Name field of the Alpha__c record to the Beta__c record.
Neetu_BansalNeetu_Bansal
Hi Tim,

When you already have Related_Alpha__c for relation, then why are you creating one more look up of Alpha on Beta? I guess in Beta_Apex_Test_Field_1__c you want to copy the value of Alpha_Test_Field_1__c. If yes, you can just create a formula field for this, using the Related_Alpha__c. If there is some specific reasons, use the below code:
// Attempting to update a lookup field on the Beta__c custom object called Beta_Apex_Test_Field_1__c with the value that is input into the Alpha__c custom object field called Alpha_Test_Field_1__c. 
trigger SyncAlphaToBeta on Alpha__c( after update )
{
	Set<String> fieldupdates = new Set<String>();
    for( Alpha__c a : Trigger.new )
	{
        if( a.Alpha_Test_Field_1__c != null 
			&& a.Alpha_Test_Field_1__c != trigger.oldMap.get( a.Id ).Alpha_Test_Field_1__c )
		{
			fieldupdates.add(a.Alpha_Test_Field_1__c);
		}
    }
    
    Map<Id, Beta__c> betas = new Map<String, Beta__c>();
    for( Beta__c b : [ SELECT Id, Name, Beta_Apex_Test_Field_1__c, Related_Alpha__c FROM Beta__c WHERE Name IN :fieldupdates ])
	{
        betas.put( b.Related_Alpha__c, b );
    }
          
    for( Alpha__c a : Trigger.new )
	{
        if( a.Alpha_Test_Field_1__c != null 
			&& a.Alpha_Test_Field_1__c != trigger.oldMap.get( a.Id ).Alpha_Test_Field_1__c )
		{
            if( betas.containsKey(a.Id) )
			{
                betas.get( a.Id ).Beta_Apex_Test_Field_1__c = a.Id;
            }
        }
    }
	
	if( betas.size() > 0 )
		update betas.values();
}
Let me know, if you need any other help. You can also contact me on my personal id i.e. Gmail id: neetu.bansal.5@gmail.com or Skype id: neetu.bansal.5

Thanks,
Neetu
This was selected as the best answer
Ketankumar PatelKetankumar Patel
1) I found problem in your SOQL. If Beta is related to Alpha then your SOQL Query should be like this. 
[SELECT Id, Name, Beta_Apex_Test_Field_1__c FROM Beta__c WHERE Beta_Apex_Test_Field_1__c  IN :fieldupdates]

2) If you are updating Alpha Test Field then you should check it's null. You should not check it's not null else you won't get into that if loop
if(a.Alpha_Test_Field_1__c == null)

3) We can't update Trigger object fields in its after update. Those fields are read-only at that time but you can create Instance of that SObject and store values in it while you are in trigger call and then update those values separately using new DML Callout. This would cost 1 additional DML to the governor Limit. While In before Call you would get system Exception error. Basically we can't update anything to Trigger object fields in it’s before update Call.

You should read this : https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm (http://You should read this : Click Here (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables_considerations.htm​))​


Here is the whole code. Try this and let me know if you have any issues or questions?
trigger SyncAlphaToBeta on Alpha__c (after update) {
    
    Set<String> fieldupdates = new Set<String>();
    for(Alpha__c a : Trigger.new) {
        fieldupdates.add(a.Id);
    }
    
    Map<String, Beta__c> betas = new Map<String, Beta__c>();
    for(Beta__c b : [SELECT Id, Name, Beta_Apex_Test_Field_1__c FROM Beta__c WHERE Beta_Apex_Test_Field_1__c  IN :fieldupdates]) {
        betas.put(b.Beta_Apex_Test_Field_1__c , b);
        
    }
    
    List<Alpha__c> updateList = new List<Alpha__c>();     
    
    for(Alpha__c a : Trigger.new) {
    
        Alpha__c updateAlpha = new Alpha__c();
        
        if(a.Alpha_Test_Field_1__c == null) {
            if(betas.containsKey(a.Id)) {
                updateAlpha.Id = a.Id;
                updateAlpha.Alpha_Test_Field_1__c  = betas.get(a.Id).Id;
                updateList.add(updateAlpha); 
            }
        }
    }
    
    update updateList;
}