I’m trying to write a trigger and having some real trouble in making it work.
Background: we adopted the Country/State picklist “Feature” last year. All the cleanup wasn’t done. We have some records that currently violate the validation rule.
Trigger: my trigger is one that updates a contact when it’s lookup account is changed. Basically, I have a field on the account and contact that mirrors, with the one at the account level taking prescedence. (Trigger on Account (after insert, after update))
Problem: If the contact has invalid country/state values, then the field validation exception is thrown when using DML statement.
update accounts;
This isn’t a problem for one-offs, but has obvious problems during bulk update/insert.
Question: So, I’ve decided to allow a partial update. Here’s the code (pretty boiler plate from what I’ve seen):
Database.SaveResult[] lsr = Database.update(updateContacts, false); for(Database.SaveResult sr : lsr){ if (!sr.isSuccess()) { for(Database.Error err : sr.getErrors()) { System.debug('The following error has occurred' + sr.getId()); System.debug(err.getStatusCode() + ': ' + err.getMessage()); System.debug('Account fields that affected this error: ' + err.getFields()); } } }
Now, when I implement this, the field validation exception is no longer thrown (or is handled somehow) and all the records update without fail.
Does this sound right? Is there a way that the database class somehow avoids the validation error that dml statements are subject to?
Any advice would be helpful. Thanks in advance.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Not all records will be updated. It is a partial update. You’re ignoring the errors (there’s no addError function), so they silently disappear.
You’ll want something like this:
Map<Id, Account> accounts = new Map<Id, Account>(); Map<Id, String> errors = new Map<Id, String>(); // Prepare data for(Contact record: Trigger.new) { if(record.AccountId != null) { accounts.put(record.AccountId, new Account(Id=record.AccountId /* etc... */)); } } // We need an ordered list Account[] accountList = accounts.values(); Database.SaveResult[] saves = Database.update(accountList, false); // Process errors for(Integer index = 0; index < saves.size(); index++) { if(!saves[index].isSuccess()) { errors.put(accountList[index].Id, saves[index].getErrors()[0].getMessage()); } } // Report errors to related contact for(Contact record: Trigger.new) { if(errors.containsKey(record.AccountId)) { record.addError('Failed to update account: '+errors.get(record.AccountId)); } }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0