+ Start a Discussion
Mayank_JoshiMayank_Joshi 

first error: INVALID_FIELD_FOR_INSERT_UPDATE

Hi Developers,

 

I am currently stuck with this below trigger : 

trigger trg_ChechForSych on Account (before insert,before update) {

List<Account> acc=[Select Name,Type,Allow_Sych__c from Account where Allow_Sych__c=True];
for(Account a:acc)
{
if(a.Allow_Sych__c==True){
insert acc;
}
else a.addError('There was a problem updating the accounts as Allow sych is not checked');

}

 

}

 

I have this trigger to fire ,if checkbox = true on account . Basically Account records are flowing through Salesforce to salesforce connection. I want to restrict records based on this checkbox value but it is not working fine and giving error at UI level .

 

Error:Apex trigger trg_ChechForSych caused an unexpected exception, contact your administrator: trg_ChechForSych: execution of BeforeUpdate caused by: System.DmlException: Insert failed. First exception on row 0 with id 0019000000DjxuSAAR; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]: Trigger.trg_ChechForSych: line 7, column 1 

 

Need help on this . 

 

Thanks in advance,

SamuelDeRyckeSamuelDeRycke

A before insert/before update trigger runs in the process of  inserting / updating. you don't have to do it in your trigger code. If you want to edit fields, you can just edit them, you have access to the full object, and its fields, and any changes you do will be inserted or updated when commiting to the database.

 

if(a.Allow_Sych__c==True){
   insert acc;
}
else{
  a.addError('There was a problem updating the accounts as Allow sych is not checked');

}

 I'm not sure what other logic you plan to implement in your trigger, but if you only want to check if Allow_Synch__c is checked, you should use a validation rule, or make the field required.

 

 

JitendraJitendra

Hi,

 

I found 2 improvment area in your code:

  1. Your trigger is running after update, so it already have ID and you cannot insert any object with ID.
  2. Second problem is, you are using insert inside loop.

 

Here, your updated code.

Please try this:

 

trigger trg_ChechForSych on Account (before insert,before update) {
	List<Account> acc=[Select Name,Type,Allow_Sych__c from Account where Allow_Sych__c=True];
	List<Account> acctoUpsert = new List<Account>();
	
	for(Account a:acc)
	{
		if(a.Allow_Sych__c==True){
			acctoUpsert.add(a);
		}
		else 
			a.addError('There was a problem updating the accounts as Allow sych is not checked');
	}
	upsert 	acctoUpsert;
}

 

Mayank_JoshiMayank_Joshi

Thanks Sdry and Jitendra ,

 

1:@Sdry The reason I am not using validation rule because there will be N nymber records flowing in from Source Org using Salesforce to salesforce connection . So, I have decided to create a trigger and filter records based on checkbox. 

Could you suggest me ,will validation rule works fine for bulk records .In that case , I am oky to use VR .

 

2@Jitendra : Thanks , I was trying to run your trigger it is giving recursive error :

Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger tttrg_ChechForSych caused an unexpected exception, contact your administrator: tttrg_ChechForSych: execution of BeforeUpdate caused by: System.DmlException: Upsert failed. First exception on row 0 with id 0019000000DjxuSAAR; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 0019000000DjxuS) is currently in trigger tttrg_ChechForSych, therefore it cannot recursively update itself: []: Trigger.tttrg_ChechForSych: line 10, column 1 . I am trying to fix it, thanks if you could help me . 

 

3: Also is there any way to restrict at record level using S2S connection ? In that case i will try to code at Source org . Currently, I am implementing it at Target org so that only filtered records will insert/update .

SamuelDeRyckeSamuelDeRycke

Validation Rule considerations in the documentation states : "The Data Loader and the Force.com API version 7 and later run validation rules."

 

Validation rules require no developer knowledge and test code, and are therefor easier to maintain. To my knowledge they will be applied to all record insert or updates, regardless or in bulk or not. This is done by salesforce. You do have to make sure, that they may break existing logic surrounding your object (But you could do that with your trigger too).

 

 

 

Mayank_JoshiMayank_Joshi

@Sdry : I will try with VR as well. 

 

Till Now , I am able to handle exception for my trigger : 

trigger tttrg_ChechForSych on Account (before insert,before update) {



List<Account> acc=[Select Name,Type,Allow_Sych__c from Account where Allow_Sych__c=True];
system.debug('test1'+acc);
List<Account> acctoUpsert = new List<Account>();
for(Account a:acc) {
if(a.Allow_Sych__c==True)
{ system.debug('test2');
acctoUpsert.add(a); }
else a.addError('There was a problem updating the accounts as Allow sych is not checked');
}
 try{
upsert acctoUpsert;
}catch (DMLException e){
system.debug('contact update failed: '+e);
 }
 }

 

But ,it is still returning same error in logs . Thus , i am not able to restrict records to insert with checkbox value 'false' . I must appreciate your help on this . Simultaneously , I am trying my hands on VR as well .:)

SamuelDeRyckeSamuelDeRycke

Well, maybe you should give the VR a try, looking at your trigger code, I just get very confused and wonder if you know what you are trying to do.

 

 

You're writing a before trigger on insert/update, you can just update the fields, you do not need to upsert, you're already in the process of doing that. You'd make an infinite iteration. 

 

Is this what you are trying to write ? : 

 

trigger tttrg_ChechForSych on Account(before insert, before update) {
    for (Account a: Trigger.new) {
        if ( a.Allow_Sych__c != True) {
            a.addError('There was a problem updating the accounts as Allow sych is not checked');
        }
    }
}

If your record has an Error, salesforce won't comit it to the database.

 

 

 

JitendraJitendra

Ohhk...

Try this,

 

trigger trg_ChechForSych on Account (before insert,before update) {
	List<Account> acc=[Select Name,Type,Allow_Sych__c from Account where Allow_Sych__c=True];

	for(Account a:acc)
	{
		if(a.Allow_Sych__c != true){
			a.addError('There was a problem updating the accounts as Allow sych is not checked');
		}			
	}
}

 

SamuelDeRyckeSamuelDeRycke

@Jitendra

 His requirement is to filter objects comming into his org with salesforce 2 salesforce, when they pass through the trigger (or validation system).

 

Quote: 

trigger trg_ChechForSych on Account (before insert,before update) {
	List<Account> acc=[Select Name,Type,Allow_Sych__c from Account where Allow_Sych__c=True]; //you will not iterate the (bulk of) record(s) given passing through the trigger (trigger.new), but all already existing records, possibly even giving a query limit exception

	for(Account a:acc)
	{
		if(a.Allow_Sych__c != true){
//this code is unreachable, your query already filters on the allow_synch__c field ... a.addError('There was a problem updating the accounts as Allow sych is not checked'); } } } 

^This will not work.

 

JPClark3JPClark3

This (Sdry's suggestion) is the correct solution.

 

You CANNOT perform a DML operation on a record that the trigger was created for. So you cannot perform an update upsert, insert, delete, ... on a list of accounts.

 

Ferthermore, you do not need to query a bunch of account records, they are given to you in the trigger.new list.

Mayank_JoshiMayank_Joshi

Yes,Now I am agree with JP and Sdry . I got confused in between List and Trigger.new . As per my intial testing I am now able to restrict records from source to target org with checkbox!=True . But , I have few more question related to this . I will list down all points in a short while . 

 

And guys this helped me to learn .So thanks @JP ,@Jitendra , @sdry .