BigObjects and Triggers

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

Captura de pantalla 2018-02-18 a las 15.16.26

and if I checked log, I also got this one.

Captura de pantalla 2018-02-18 a las 15.16.54

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

Captura de pantalla 2018-02-18 a las 16.37.46

Captura de pantalla 2018-02-18 a las 16.39.40.png

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.