在对象创建期间将日期字段设置为 null 后构造函数未定义错误

Constructor not defined error after setting date fields as null during object creation

我创建了一个包装器 class 来创建对象并将其作为请求发送到第三方系统。它运作良好。但是在我添加了数据类型日期的两个新参数之后,出现以下错误。

Constructor not defined: [SFDC_DataObject.CustomerAccountObject].<Constructor>(Id, String, Id, String, Id, String, Integer, NULL, String, String, Id, String, NULL, String, String, String, String)

我正在创建和发送的请求如下。

SFDC_DataObject.CustomerAccountObject cusAccObj = new SFDC_DataObject.CustomerAccountObject(o.AccountId, o.Customer_Name__c, o.Agency_Name__r.Id,o.Agency_Name_OB__c, o.Opportunity.OwnerId, o.Opportunity.Owner.FederationIdentifier, PrimarySalesSplitPercent, null, secSOSalesforceId.get(o.OpportunityId), secSOSalesforceEmail.get(o.OpportunityId), o.Opportunity.Customer_Success_Manage__r.Id, o.Opportunity.Customer_Success_Manage__r.FederationIdentifier, null, o.Billing_Email__c, o.Billing_Phone__c, o.Bill_To_Name__c, o.Billing_Notes__c);

我对同一对象的包装 class 如下所示。

public class CustomerAccountObject {
        public String  sfCustomerId;
        public String  customerName;
        public String  sfAgencyId;
        public String  agencyName;
        public String  sfPrimarySalesOwnerId;
        public String  primarySalesOwnerEmail;
        public Integer primarySalesOwnerPercentage;
        public Date    primarySalesOwnerEffectiveFrom;
        public String  sfSecondarySalesOwnerId;
        public String  secondarySalesOwnerEmail;
        public Date    secondarySalesOwnerEffectiveFrom;
        public String  sfAccountManagerId;
        public String  accountManagerEmail;
        public String  billingEmail;
        public String  billingPhone;
        public String  billingName;
        public String  billingNotes;

        public CustomerAccountObject() {}

        public CustomerAccountObject(String sfCustomerId, String customerName, String sfAgencyId, String agencyName, String sfPrimarySalesOwnerId, String primarySalesOwnerEmail, Integer primarySalesOwnerPercentage, Date primarySalesOwnerEffectiveFrom, String sfSecondarySalesOwnerId, String secondarySalesOwnerEmail, Date secondarySalesOwnerEffectiveFrom, String sfAccountManagerId, String accountManagerEmail, String billingEmail, String billingPhone, String billingName, String billingNotes) {
            this.sfCustomerId                     = sfCustomerId;
            this.customerName                     = customerName;
            this.sfAgencyId                       = sfAgencyId;
            this.agencyName                       = agencyName;
            this.sfPrimarySalesOwnerId            = sfPrimarySalesOwnerId;
            this.primarySalesOwnerEmail           = primarySalesOwnerEmail;
            this.primarySalesOwnerPercentage      = primarySalesOwnerPercentage;
            this.primarySalesOwnerEffectiveFrom   = primarySalesOwnerEffectiveFrom;
            this.sfSecondarySalesOwnerId          = sfSecondarySalesOwnerId;
            this.secondarySalesOwnerEmail         = secondarySalesOwnerEmail;
            this.secondarySalesOwnerEffectiveFrom = secondarySalesOwnerEffectiveFrom;
            this.sfAccountManagerId               = sfAccountManagerId;
            this.accountManagerEmail              = accountManagerEmail;
            this.billingEmail                     = billingEmail;
            this.billingPhone                     = billingPhone;
            this.billingName                      = billingName;
            this.billingNotes                     = billingNotes;
        }
    }

我在对象创建期间为日期参数添加空值后开始出现错误,即 primarySalesOwnerEffectiveFromsecondarySalesOwnerEffectiveFrom

任何人都可以让我知道我在这里做错了什么。

顺序错误。

在 c-tor 定义中你有

String sfCustomerId, String customerName, String sfAgencyId, String agencyName, String sfPrimarySalesOwnerId, String primarySalesOwnerEmail, Integer primarySalesOwnerPercentage, Date primarySalesOwnerEffectiveFrom, String sfSecondarySalesOwnerId, String secondarySalesOwnerEmail, Date secondarySalesOwnerEffectiveFrom + 6 more Strings

所以

... Integer, Date, String, String, Date, ...

但是调用它的代码

o.AccountId, o.Customer_Name__c, o.Agency_Name__r.Id,o.Agency_Name_OB__c, o.Opportunity.OwnerId, o.Opportunity.Owner.FederationIdentifier, PrimarySalesSplitPercent, null, secSOSalesforceId.get(o.OpportunityId), secSOSalesforceEmail.get(o.OpportunityId), o.Opportunity.Customer_Success_Manage__r.Id, o.Opportunity.Customer_Success_Manage__r.FederationIdentifier, null, + 4 strings

第二个空值前多了两个字符串。之后只有 4 个字符串。您需要在 secSOSalesforceEmail?

之后注入空值

随着时间的推移,这只会变得更难维护。考虑制作一个简单的构造函数并制作属性 public。然后,您可以在正常调用的构造函数之后设置它们。如果你不需要日期,你只是不写设置日期字段的行,而不是在正确的位置注入 null。

后续编辑

不确定是否有该技术的官方指南或博客 post。 Apex-PMD 之类的工具会在您创建带有太多参数的方法时抱怨,例如“避免长参数列表”之类的规则。

一种方法是做这样的事情:

SFDC_DataObject.CustomerAccountObject cusAccObj = new SFDC_DataObject.CustomerAccountObject();
cusAccObj.sfCustomerId                      = o.AccountId;
cusAccObj.customerName                      = o.Customer_Name__c;
cusAccObj.sfAgencyId                        = o.Agency_Name__c;
cusAccObj.agencyName                        = o.Agency_Name_OB__c;
cusAccObj.sfPrimarySalesOwnerId             = o.Opportunity.OwnerId;
cusAccObj.primarySalesOwnerEmail            = o.Opportunity.Owner?.FederationIdentifier;
cusAccObj.primarySalesOwnerPercentage       = PrimarySalesSplitPercent;
// cusAccObj.primarySalesOwnerEffectiveFrom = null; // just don't bother with the line?
cusAccObj.sfSecondarySalesOwnerId           = secSOSalesforceId.get(o.OpportunityId);
// ..

这不是很面向对象,不是很优雅,但调用者可以完全控制映射。如果您需要映射新字段并且已将其复制粘贴到 10 个位置,则会出现问题。您必须全部更新它们(这比向长调用添加第 N 个参数更容易,但仍然如此)

另一种方法是创建一个基线构造函数,它接受整个 Order 对象(它是一个订单,对吧?),它会在内部映射字段。然后如果需要 - 你在构造函数之后指定一些额外的字段。还是做几个构造函数?

public CustomerAccountObject(){
    // I'm parameterless, I'm doing nothing! I'm just here if somebody needs a really custom field mapping or JSON deserialisations need a parameterless one
}
public CustomerAccountObject(Order o){
    // I can map all fields from Order! Want to map new field? Just chuck it in here!
    sfCustomerId = o.AccountId;
    // ...
}
public CustomerAccountObject(Order o, Map<Id, String> secSOSalesforceId, Map<Id, String> secSOSalesforceEmail){
    // I can do everything above and few more fields too!
    this(o);
    sfSecondarySalesOwnerId = secSOSalesforceId.get(o.OpportunityId);
    secondarySalesOwnerEmail = secSOSalesforceEmail.get(o.OpportunityId);
}

您有一些代码重用,订单字段映射仅在 1 个地方定义,将来只需更改 1 行。你不会再到处狂欢 this 了。然后,如果您确实需要最后一个构造函数,则调用您的调用,或者调用只需要 Order o 的构造函数,然后在它完成后设置 2 个额外字段。