0

I am doing bulk cloning of records and modifying some field values and reinserting records inside the future method, As the DML happens in the future method if there are any DML failures due to validation rules, not able to report to the user on UI.

Is there a way in apex, where I can run validation rules against sobject records and know the failures in advance in realtime before pushing it the future method? The object has around 25 validation rules, I don't want to implement again in apex.

I am from ruby on rails background, Rails has a option to validate record beforehand i.e. before actual DML. I am looking for something this way in apex.

Example rails:

user_details = UserDetails.new
user_details.valid?
#=> false
user_details.errors.full_messages
#=> ["Name can't be blank", "Email can't be blank"]
user_details2 = UserDetails.new("Phil", "Phil's email")
user_details2.valid?
#=> true
4
  • Why is the DML in a future method? The reason for that likely also constrains your options in your starting code.
    – David Reed
    Aug 19, 2020 at 17:54
  • I am doing the bulk operation, which is hitting the governor's CPU limit due to fatty triggers. As in async, we get 6x cpu time, so moved insert to future. Aug 19, 2020 at 17:56
  • salesforce.stackexchange.com/questions/219148/… - can we achieve this from apex for insert or update events? Aug 19, 2020 at 18:11
  • Don't have full details on your use case but here is an idea: Let's say UI knows that it has to insert 20,000 rows, then send only 5000 at a time to Apex. Apex will insert those 5000 and report any errors. If there are no errors, send next 5000 and repeat this. With each invocation of Apex, limits are reset.
    – javanoob
    Aug 19, 2020 at 18:41

2 Answers 2

2

You would need to manage splitting records into governor-compatible chunks in the UI. Your front end could then make multiple server-side calls (whether you are in Lightning or Visualforce) with individual chunks of records to insert and get back any error details.

What you would gain by this approach is that the future method would not be necessary - you'd insert all of the records synchronously and return any error information to the frontend. What you'd lose is that the entire operation would span multiple transactions, and hence would not be atomic.

Your client-side code would have to be responsible for tracking progress across all of the batches submitted by the frontend, and you'd have to design an approach to manage a kind of "rollback" if some of the records succeeded and others did not. You could do a kind of trial insert followed by a rollback to check validity across all records before inserting any for real, but this is not a perfect guarantee.

1

The only way to do it would be to actually perform a DML, which presumably defeats the purpose:

SavePoint sp = Database.setSavePoint();
Database.SaveResult[] results = Database.insert(records, false);
sObject[] sendToFuture = new sObject[0];
for(Integer i = 0, s = results.size(); i < s; i++) {
  if(!results[i].isSuccess()) {
    reportAnErrorWith(records[i], results[i]);
  } else {
    sendToFuture.add(records[i].clone(false, false, false));
  }
}
Database.rollback(sp);
futureMethod(sendToFuture);

This is the only way you would get this to work, at which point, you may as well just keep the records inserted and not use the future method.

3
  • Savepoint and rollback good suggestion, did not come to my mind, thanks. Aug 19, 2020 at 18:05
  • If code hits the governor's CPU limit, I won't be able to validate all records and report validation failures in realtime. Aug 19, 2020 at 18:10
  • 1
    @SatishakumarAwati That's correct. The only way to actually validate validation rules is to execute the logic. One trick that may work is that if you use mostly triggers, you could use a trigger framework that disables actual trigger execution, thus drastically reducing the time spent in trigger logic (and overall CPU time). This is what I'd do in our org if I needed to validate records before asynchronous processing.
    – sfdcfox
    Aug 19, 2020 at 18:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .