We have a product configurator app that converts OpportunityLineItems to QuoteLineItems. We implemented a new solution with custom metadata relationships to dynamically map field values between the 2 objects without having to update the code every time a new field is added.
We are running into a problem with a boolean field on insert where the value is null/not set.
System.DmlException: Insert failed. First exception on row 0; first error: INVALID_TYPE_ON_FIELD_IN_RECORD, 24x7 Subscription Support: value not of required type: : [X24x7_Subscription_Support__c]
I have confirmed that the field exists on both objects and is of the same type.
I have read that by using sObject.get(field) should automatically cast null values to false. However, we are doing this and it is still failing.
This is the simplified version of the code that converts the line items:
//metadata queried here in a different method
Set<String> dynamicFields = new Set<String>();
for (Configurator_Field__mdt field : [SELECT Id, Destination_Field__r.QualifiedApiName FROM Configurator_Field__mdt]) {
dynamicFields.add(field.Destination_Field__r.QualifiedApiName);
}
//metadata fields are passed to a method that does the conversion
//note the use of SObject.get()
public static QuoteLineItem CreateQLIFromOLI(OpportunityLineItem oli, Set<String> dynamicFields)
{
QuoteLineItem qli = new QuoteLineItem();
for (String field : dynamicFields) {
qli.put(field, oli.get(field));
}
return qli;
}
//insertion happens after the quote line item is returned
insert qli;
Can someone recommend a way to handle null boolean fields while avoiding hardcoded field mapping?
Sobject.get(field)
should be used when you WANT the null value.