Sometimes when I publish platform event on change of certain Record, Platform Event Trigger fires with old data. If I publish event on insert, sometimes record is not visible for query.
To test it on clean Salesforce Org I created new scratch org without any custom logic. I followed those steps:
- Create Platform Event (PE__e) with fields for WorkOrder Id and for information whether it is Insert or Update
- Create Trigger on Work Order to publish platform events on After Insert/Update
- Create object LOG with fields for Work Order Description and for trigger context.
- Create Trigger for PE__e which is querying Work Orders with given ids, and then inserts all logs with queried Work Order Description and Trigger context
Run following code:
List<WorkOrder> wos = new List<WorkOrder>(); for(Integer i = 0; i < 100; i++){ WorkOrder wo = new WorkOrder(); wo.Description = 'A_' + i; wo.Status = 'New'; wos.add(wo); } insert wos;
Run following code:
List<WorkOrder> wors = [SELECT Id, Status, Description FROM WorkOrder]; for(WorkOrder wo : wors){ wo.Status = 'In Progress'; wo.Description = wo.Description + '|a'; } update wors;
Repeat step 6.
As you can see some of records are processed with updated Description and some are not. Is there any soloution for this? Or maybe it is expected behavior?
Work Order Trigger:
trigger WOR_TH on WorkOrder (
after insert,
after update) {
List<PF__e> pfs = new List<PF__e>();
for(WorkOrder wo : Trigger.new){
if(Trigger.isInsert){
pfs.add(new PF__e(Data__c = wo.Id, Additional__c = 'Insert'));
}
if(Trigger.isUpdate){
pfs.add(new PF__e(Data__c = wo.Id, Additional__c = 'Update'));
}
}
System.debug(pfs);
EventBus.publish(pfs);
}
PF__e trigger:
trigger PF_TH on PF__e (after insert) {
String query = 'SELECT ';
try{
List<Log__c> logs = new List<Log__c>();
Map<Id, String> ids = new Map<Id, String>();
for(PF__e e : Trigger.new){
ids.put(e.Data__c, e.ADDITIONAL__c);
}
insert new Log__c(log__c = JSON.serialize(ids));
Schema.DescribeSObjectResult a_desc = WorkOrder.sObjectType.getDescribe();
Map<String, Schema.SObjectField> a_fields = a_desc.fields.getMap();
for(Schema.sObjectField fld : a_fields.values()){
query += fld.getDescribe().getName() + ',';
}
query = query.removeEnd(',');
List<Id> idsList = new List<Id>(ids.keySet());
query += ' FROM WorkOrder WHERE Id in :idsList';
for(WorkOrder wo : Database.query(query)){
Log__c log = new Log__c();
log.log__c = wo.Description;
log.ADDITIONAL__c = ids.get(wo.Id);
logs.add(log);
}
insert logs;
}catch(Exception e){
insert new Log__c(log__c = e.getMessage() + ' || ' + e.getStackTraceString() + ' || ' + query);
}
}