Some months ago I wrote an entry about BigObjects and since that moment I go lot of comments with questions and some useful information that I missed in my post and I would like to include here because sometimes, we do not read comments.
Not all SOQL statements are valid. For now, the !=, LIKE, NOT IN, EXCLUDES, and INCLUDES operators are not valid in any query.
There are already some Standard Big Objects like FieldHistoryArchive, so do not try to create one directly, and check before if it already exist.
Unfortunately SOSL is not supported by BigObjects.
But maybe the most important one was the fact that people was not able to create BigObject records from Triggers. It was a big surprise for me because documentation said that you could not create triggers related to a Big Object, but nothing about not be able to create Big Object records from triggers. So today I decided to give it a try.
If you have taken a look at my blog, the use case was to archive Code Review records so that we could end up with Code Review History records. Although it doesn’t make too much sense, create History records in a trigger, I decided to make it simple and continue with these objects.
So the first idea was to create a Trigger related to CodeReview__c:
trigger CodeReviewTrigger on CodeReview__c (after insert) { List<CodeReviewHistoric__b> crhToInsert = new List<CodeReviewHistoric__b>(); for (CodeReview__c cr: Trigger.new) { CodeReviewHistoric__b crh = new CodeReviewHistoric__b(); crh.CanBeMerged__c = cr.CanBeMerged__c ? 'true' : 'false'; crh.CodeReviewDate__c = cr.CodeReviewDate__c; crh.Comments__c = cr.Comments__c; crh.Employee__c = cr.Employee__c; crh.Score__c = cr.Score__c; crh.Story__c = cr.Story__c; crhToInsert.add(crh); } Database.insertImmediate(crhToInsert); }
However, when I tried to create a Code Review record via the UI, I got below error
and if I checked log, I also got this one.
So came back to BigObjects product manager suggestion:
However a workaround could be to put the insertImmediate() call into a queueable method
But why queuable method? I think the key point is that we need a different context, a new transaction, so it doesn’t matter the way to get it, and I decided to keep things simple using a @future method in order to perform the Database.insertInmediate action. Then, this method will be called from the trigger.
But this annotation has several restrictions, like argument types. It doesn’t support a list of SObjects, but it allows a List of Ids.
So Trigger will look like this:
trigger CodeReviewTrigger on CodeReview__c (after insert) { List<Id> codeReviewIds = new List<Id>(); for (CodeReview__c cr: Trigger.new) { codeReviewIds.add(cr.Id); } AsyncProcess.createBigObjectRecords(codeReviewIds); }
And @future one like this:
public with sharing class AsyncProcess { @future public static void createBigObjectRecords(List<Id> crIds) { List<CodeReviewHistory__b> crhToInsert = new List<CodeReviewHistory__b>(); for (CodeReview__c cr: [Select Id, CanBeMerged__c, CodeReviewDate__c, Comments__c, Employee__c, Score__c, Story__c From CodeReview__c Where Id In :crIds]) { CodeReviewHistory__b crh = new CodeReviewHistory__b(); crh.CanBeMerged__c = cr.CanBeMerged__c ? 'true' : 'false'; crh.CodeReviewDate__c = cr.CodeReviewDate__c; crh.Comments__c = cr.Comments__c; crh.Employee__c = cr.Employee__c; crh.Score__c = cr.Score__c; crh.Story__c = cr.Story__c; crhToInsert.add(crh); } Database.insertImmediate(crhToInsert); } }
And now it works sucessfuly
Any other options? Batch Apex, Queueable, even, you can use Async SOQL via a http call.
I’m sure that I still miss things about BigObjects but another amazing resource to check is the Salesforce MVP Alba A. Rivas blogs about this technology.