+ Start a Discussion
hal9001hal9001 

Trigger works before update, but not before insert. Why?

I have the following trigger.  When inserting a record, the try fails. When updating, it works. It is as if Trigger.new is empty for inserts. Why is that?

 

trigger validateTransaction on Transaction__c (before insert, before update) {
  
  try{   
    for (Transaction__c trans : Trigger.new) 
 {
        Transaction__c d = [SELECT Quantity__c FROM Transaction__c WHERE Id =:trans.Id];
        trans.Transaction_Type__c = 'OK';
          }
  }
  catch(Exception e){
    for (Transaction__c trans : Trigger.new) 
        trans.Transaction_Type__c = 'error';
  }
  
}

Starz26Starz26

Becaue on the insert there is no ID yet. Thus you SOQL  has no records to assign:

 


        Transaction__c d = [SELECT Quantity__c FROM Transaction__c WHERE Id =:trans.Id];

 

You should not need the before insert trigger here as the before update will fire after the insert and it will contain the ID and thus update the record during the before update trigger.

 

Also, why the SOQL assignment to a new sObject? is there code missing? you do not do anything with the "d"

 


 


vishal@forcevishal@force

Starz is correct. In a before insert trigger, you never get an id since the record is yet to be inserted in the database. 

 

Btw, you don't even need to query your record, it is already there in your trigger.new list. So all you need to do is update that field with value "OK" as you are doing. Rest will be done by the trigger itself, for both the cases : before insert and before update.

trigger validateTransaction on Transaction__c (before insert, before update) 
{
  
  try
  {   
	for (Transaction__c trans : Trigger.new) 
	{
		// Transaction__c d = [SELECT Quantity__c FROM Transaction__c WHERE Id =:trans.Id]; NO NEED TO QUERY, since you are iterating through the new list.
		trans.Transaction_Type__c = 'OK';
	}
  }
  catch(Exception e)
  {
    for (Transaction__c trans : Trigger.new) 
        trans.Transaction_Type__c = 'error';
  }
  
}

 Hope this clears your doubt. 

hal9001hal9001

Thanks for the reply.  I simplified the query for troubleshooting purposes -- that's why d is not used.

 

I'm querying the record because I need to get the values in some child fields which are not available in trigger.new. Here is the full query.  How can I access those child fields from trigger.new in a way that will work for inserts and updates?

 

trigger validateTransaction2 on Transaction__c (before insert, before update) {
   
//make a list of transaction definitions


Map<String,String> defs = new Map<String, String>();

Map<String, Transaction_Definition__c> definitions = new Map<String, Transaction_Definition__c>(
[select TransactionTypeKey__c,Transaction_Definition__c.Name from Transaction_Definition__c]);
for (Transaction_Definition__c d :definitions.values() )
{
    defs.put(d.TransactionTypeKey__c,d.Name);
}
  

//lookup transaction definition and populate transaction name

 

  try{   
    for (Transaction__c trans : Trigger.new) 
 {

//get sender type and receiver type -- need a way to do this that will work for inserts

        Transaction__c d = [SELECT sender__r.location_type__r.name, receiver__r.location_type__r.name FROM Transaction__c WHERE Id =:trans.Id];

//concatenate sender and receiver type to make key to transaction type

        String f = d.sender__r.location_type__r.name + ' -> ' + d.receiver__r.location_type__r.name;

//lookup transaction type in list and update Transaction_Type__c

        trans.Transaction_Type__c = defs.get(f);
          }
  }
  catch(Exception e){
    for (Transaction__c trans : Trigger.new) 
        trans.Transaction_Type__c = 'error';
  }
  
}

Starz26Starz26

How are the two objects Transactions__c and Transaction_Definitions__c related?