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
Abilash Kosigi 8Abilash Kosigi 8 

Populating Lookup Field Value in an Apex Trigger

Hi,

When I am trying to run this code, I am getting null pointer exception saying attempt to de-reference a null object at the line highlighted in the code. 
This is because the highlighted field is the lookup field. Can anyone please help how to assign values to the lookup fields like this in apex trigger.

trigger setListView on Account(after insert) {
if(CheckRecursiveTrigger.runOnce())
{
for (Account act: Trigger.new)
{
Account acct = [select Id,  Name from Account where Id IN : trigger.new];
String oppname = acct.name;
Opportunity[] oppSave = new Opportunity[] {};
Opportunity opp= new Opportunity();
opp.Name= oppname + '-opp' ;
opp.stagename= 'Prospecting';
opp.CloseDate = date.today();

Account ack = [Select Id from Account where name = :oppname limit 1];

opp.Account.name= ack.id;
oppSave.add(opp);
insert oppSave;
}
}
}
Ramu_SFDCRamu_SFDC
add an if condition before that line to verify if ack is not null and put the next lines within the if condition something as below

if(ack!=null){

opp.Account.name= ack.id;
oppSave.add(opp);
insert oppSave;

}
AshwaniAshwani
You Trigger is completely wrong before doing anything you must implement Trigger best practices first

Read here: https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_bestpract.htm

Also, You can not access lookup object field from its instance like opp.Account.name= ack.id; "Account" doesn't exist here.

Simply do: opp.AccountId = ack.id;
Abilash Kosigi 8Abilash Kosigi 8
Ramu, Reid,

Thanks for your quick reply. Unfortunately, both the suggestions did not work.  
opp. AccountId -- there is no field on opportunity as such.

Any other suggestion or work around for this please..
Martijn SchwarzerMartijn Schwarzer
Hi there,

First of all, I agree with Reid, please implement the Trigger best practices, especially bulkifying your code.

The field Account on the Opportunity is a lookup field, which you can populate directly with the Id of the Account record.
Since you have an after insert trigger, the ID of the Account is already available and you don't need to query it.
(Besides, no queries inside loops = best practice)

You should create a list for records to update outside your for-loop, then populate it inside your for-loop.
After the for-loop you can insert the entire list at once.


Your code should look something like this:

trigger setListView on Account(after insert) {
  if(CheckRecursiveTrigger.runOnce()){
  
  Opportunity[] oppSave = new Opportunity[] {};
 
  for (Account act: Trigger.new){
   
    String oppname = acct.name;
    Opportunity opp = new Opportunity();
    opp.Name = oppname + '-opp' ;
    opp.stagename= 'Prospecting';
    opp.CloseDate = date.today();
  
    opp.Account = act.id;

    oppSave.add(opp);
   }
  
   insert oppSave;
  }
}

Hope this helps. If so, please mark it as best answer, thanks.

Best Regards,
Martijn Schwärzer
Marc D BehrMarc D Behr
Looking at the following lines:
for (Account act: Trigger.new)
{
Account acct = [select Id,  Name from Account where Id IN : trigger.new];

The for line says to loop over the objects that caused the trigger one at a time and assign them to the Account loop variable called 'act'. Then inside the loop you lookup the account ID and Name from the same list of variables, but the acct variable will only hold a single object (despite the fact that the select statement could return  more than one which would result in an exception being generated. 

Next you define a list of opportunities as well as a single opportunity
Opportunity[] oppSave = new Opportunity[] {};
Opportunity opp= new Opportunity();

You fill in the single opportunity details and then look up the account again (not sure why) before saving the single opp into the oppSave list and finially saving the list (which will always have one entry). 

I thin what you want is more this this:
for (Account act: Trigger.new)
{
Opportunity opp= new Opportunity();
opp.Name= act.name + '-opp' ;
opp.stagename= 'Prospecting';
opp.CloseDate = date.today();
opp.Account= act.id;
insert opp;
}

This is still not the best way by any means (it should have try/catch around the insert and should really be written to handle bulk operations better), but I think this is better than what you started with.