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
B2AB2A 

Save error: file is not writeable: Account.id

I'm in a pickle - how do I update an account record if I cannot write to account.id for storing in a LIST. 

 

Below is the code in which i'm getting the error: "Save error: file is not writeable: Account.id"

 

What should I do to get past this?  Thanks for any help!

 

List<Account> Account_list = [Select Id, Last_meeting__c From Account where Id IN: Ids]; For(Meetings__c MyItem : trigger.new){ Account acc = new Account(); acc.id = MyItem.Account__r.id; Account_list.add(acc); } update(Account_list);

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Cool_DevloperCool_Devloper

As per what i know, relationship fields like "(NewRecord.Account__r.id)" do not work directly in trigger.new!

You need to write an SOQL to get the values. So, i am sure using it in the straightforward way "NewRecord.Account__c" should work. You can probably give a system.debug() to see what values come in this field for the custom object.

Cool_D

All Answers

gm_sfdc_powerdegm_sfdc_powerde
What are you trying to update here?  ID is the system identifier and cannot be updated.
B2AB2A

THanks for the response! 

 

 I'm trying to update a date field on an account record.  THe trigger fires when a custom object (which is linked to account via lookup field) has been created or editted. 

 

A date field on this custom object needs to be updated onto a custom date field on the associated account record.

gm_sfdc_powerdegm_sfdc_powerde
Got it. can you post your complete code here?
B2AB2A

Here is the code: I'm stuck at the fact that id is note writeable, so I'm not sure what route I need to take to get the trigger to write to the custom date field on the associated account record :(

 

It stops the code save at "myAccount.id = MyItem.account__r.id;" obviously since ID is read only.

 

Thanks for the assistance!

 

trigger UpdateAccountFromMeeting on Meetings__c (after update, after insert) { //trigger to test update of related account records based on child object(Meeting__c) //this is testing on my dev instance Set<Id> Ids = new Set<Id>(); For (Meetings__c m : trigger.new){ Ids.add(m.Account__r.id); } List<Account> Account_list = [Select Id, Last_meeting__c From Account where Id IN: Ids]; Account myAccount = new Account(); For(Meetings__c MyItem : trigger.new){ myAccount.id = MyItem.account__r.id; myAccount.Last_meeting__c = MyItem.meeting_date__c; Account_list.add(myAccount); } update(Account_list); }

 

Cool_DevloperCool_Devloper

Well, you had to do this in the Ajax Toolkit, but in APEX, you dont need to instantiate the object and assign the ID to update it.

You can directly add the object in a list and fire an update on that!

Cool_D

B2AB2A

So in Apex you do not need to instantiate the object (MyAccount)?

 

Hence I wouldn't need to use -> Account_list.add(myAccount);   ?

 

Then how would I get the date value from the custom object and store it with the associated account ID?

Cool_DevloperCool_Devloper

No, you would need to add the Account into the list for doing a Bulk Update. But what i mean is that, you dont need to create/instantiate a new Account object and set it's ID as you are doing in your code.

That is what is causing the exception. You have to update the same Accounts which you have got in your query updating the requisite field from the corresponding custom object relate resord by running a loop over it! 

Cool_D 

Cool_DevloperCool_Devloper

I would re-write the last part of your code like this-

 

List<Account> Account_List = new list<Account>(); 

Map<Id,Account> Account_Map = new Map<Id,Account>([Select Id, Last_meeting__c From Account where Id IN: Ids]);

For(Meetings__c MyItem : trigger.new)

{

   Account_Map.get(MyItem.account__r.id).Last_meeting__c = MyItem.meeting_date__c;

   Account_list.add(Account_Map.get(MyItem.account__r.id));

}

update(Account_list); 

 

Cool_D 

B2AB2A

I tried something I created identical to that (using MAP), and it saves!  However, when trying to save the Meeting record i get the same message:

 

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger UpdateAccountFromMeeting caused an unexpected exception, contact your administrator: UpdateAccountFromMeeting: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.UpdateAccountFromMeeting: line 41, column 36
B2AB2A
It's rooting from anytime I use "MyItem.account__r.id"
Cool_DevloperCool_Devloper

Oops ... i did not notice that!

Instead of using that "__r.ID", y don't u use the lookup field directly which you have configured?

Also, is the record you are testing with, having a value for the lookup field to account? It seems, it is coming as NULL in the map!

Cool_D 

B2AB2A

Thanks for the assistance so far.  Unfortunatley it's still not working!

 

I changed it to the following code, but now i'm getting the error given in the next posting.

 

List<Account> Account_List = new List<Account>(); Map<Id,Account> Account_Map = new Map<Id, Account>([Select Id, Last_meeting__c From Account Where Id IN: Ids]); For(Meetings__c m : trigger.new){ Account_Map.get(m.Account__c).Last_meeting__c = m.Meeting_date__c; Account_list.add(Account_Map.get(m.account__r.id)); }

 

B2AB2A

Here is the error when trying to save a "Meeting" record:

 

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger UpdateAccountFromMeeting caused an unexpected exception, contact your administrator: UpdateAccountFromMeeting: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.UpdateAccountFromMeeting: line 41, column 33

 

It's reference where I have m.Account__c,  so for some reason it is coming up as NULL?

 

Cool_DevloperCool_Devloper

Hi, 

There is still one line in your code which needs to be modified -

 

"Account_list.add(Account_Map.get(m.account__r.id));"

 

If you still get the above mentioned exception, then the only reason could be that you custom object record does not hold any value for Account ID.

In that case, you can put some check conditions in your code, to avoid the exception!

Cool_D 

gm_sfdc_powerdegm_sfdc_powerde
You cannot update meeting record in the "after" trigger for the same record.  You can however make it a "before" trigger and change the record without explicitly calling update.
Cool_DevloperCool_Devloper

The Trigger is running on "Meeting__c" object and the object being updated is "Account".

So, its perfectly fine.

Moreover, you wun't hv got Null Pointer Exception if that would have been the case.

Cool_D 

B2AB2A
Cool, i'm using "

"Account_list.add(Account_Map.get(m.account__r.id));" but i'm still getting the null pointer exception save message as I had thought.

 

So, if an ID cannot be found, how can an account be updated?

 

 

Cool_DevloperCool_Devloper

Change the stmt to-

 

"Account_list.add(Account_Map.get(m.Account__c));"

 

Also, put some NULL checks in your code like-

 

"if(Account_Map.get(m.Account__c) <> null)"

 

This would help you to afoid the exceptions in case, account value is not existing!

Cool_D 

 

 

B2AB2A

I was testing around and the initial way I had the code set up worked when it was all standard objects (date on contact record updates date on account record which is parent).

 

However, when I try the same thing with custom object being child I get an error when saving the custom object record (Meeting) ... below is the code  (the area highlighted in red is the problem area)

trigger UpdateAccount_fromMeetingDate on Meetings__c (after insert, after update) { //Triger to test update of relatwed records based on child trigger integer MyCounter=0; Set<Id> Ids = new Set<Id>(); For (Meetings__c NewRecord : trigger.new){ Ids.add(NewRecord.Account__r.id); } List<Account> Account_list = [Select Id,Name, LastMeeting__c From Account Where Id IN :Ids ]; For (Meetings__c MyItem : trigger.new){ Account_list[MyCounter].LastMeeting__c = MyItem.MeetingDate__c; MyCounter++; } update(Account_list); }

The error I get is "System.ListException: List index out of bounds: 0: Trigger.UpdateAccount_fromMeetingDate: line 27, column 22.

 

 

 

When I was using std object (Contact) I never had a problem with indexing and I was using accountID to ref Account (eg. NewRecord.AccountID), rather than what I had to do with a custom object (NewRecord.Account__r.id).   I think the problem is rooting with the ID not saving to the list and thus not having a valid index being used?

 

Any ideas on ?  I think i'm close, i just can't figure it out! :(

Cool_DevloperCool_Devloper

Yes, the problem is that the ID is not populated using the custom relationship (NewRecord.Account__r.id).

That's y i asked you to test with the updated code and confirm if you are getting values in the SOQL query or not.

What i feel is that the list is coming empty!!

Cool_D

B2AB2A

I inserted this if statement checking the first index value and whether it's null, and it removes the error, but that shows that index value of 0 may have a value.

For (Meetings__c MyItem : trigger.new){ if(Account_list[0] == null){ Account_list[MyCounter].LastMeeting__c = MyItem.MeetingDate__c; } MyCounter++; }

 

 

if i make it "!= null" it enters the if statement.  So i'm rather confused now :S

B2AB2A

Guys,

I got it to work!  The code is the same, however, the main difference is that I added a hidden field the the custom object which is of type formula and from there I got the accountID (accountID__c). 

 

the formula field just does the work of getting the related accounts ID and it seems to do the trick.  I think this is a workaround but not the most elegant fix. 

 

So i'm using

"Ids.add(NewRecord.AccountID__c);" and it makes all the difference.

 

it sucks how "Ids.add(NewRecord.Account__r.id)" does work, which would of made this way less time consuming!

 

Please, any ideas on why this is happening in the first place?

Cool_DevloperCool_Devloper

As per what i know, relationship fields like "(NewRecord.Account__r.id)" do not work directly in trigger.new!

You need to write an SOQL to get the values. So, i am sure using it in the straightforward way "NewRecord.Account__c" should work. You can probably give a system.debug() to see what values come in this field for the custom object.

Cool_D

This was selected as the best answer
B2AB2A

I'm actually new to apex since I do mostly admin stuff.  Do you recommend any readings specifically to testing or using calles liek system.debug?

 

Thanks

Cool_DevloperCool_Devloper

gotcha....no worries:)

you can read through the "Testing Apex" portion of the apex guide!

Cool_D

B2AB2A

Hey guys,

Thanks for all the help!!

 

Cool D, I will read the guide shortly!