• splitthebills1.3947274848456084E12
  • NEWBIE
  • 0 Points
  • Member since 2014

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 4
    Replies
Hi everyone,

We have written some code to create objects and insert via Database.executeBatch processes. This has been working fine for a long time, but recently, the inserts have stopped working in certain (unknown) circumstances.

I've created some test code to see if i can find the issue, and all i can find is that if i pass batches of around 30 to Database.executeBatch, they are inserted, but if i pass batches of around 70, these are not inserted. Either way, the batchable process emails us to say there were no errors.

The code that does all this is pretty straightforward and follows the SF rules to avoid running out of SOQL statements, plus the script only creates 2 batches.

Below is the test code that works, but doesn't result in payments being inserted.

Set<Id> invoiceIds = new Set<Id>{'a1SD0000000gzQWMAY', 'a1SD0000000gzQeMAI', 'a1SD0000000gzQiMAI', 'a1SD0000000gzQqMAI', 'a1SD0000000gzTeMAI', 'a1SD0000000gzTjMAI', 'a1SD0000000gzVYMAY', 'a1SD0000000gzVgMAI', 'a1SD0000000gzVhMAI', 'a1SD0000000gzVkMAI', 'a1SD0000000gzVmMAI', 'a1SD0000000gzVpMAI', 'a1SD0000000gzVwMAI', 'a1SD0000000gzVxMAI', 'a1SD0000000gzVzMAI', 'a1SD0000000gzW0MAI', 'a1SD0000000gzWDMAY', 'a1SD0000000gzWMMAY', 'a1SD0000000gzWOMAY', 'a1SD0000000gzWPMAY', 'a1SD0000000gzWSMAY', 'a1SD0000000gzWhMAI', 'a1SD0000000gzWkMAI', 'a1SD0000000gzWwMAI', 'a1SD0000000gzWxMAI', 'a1SD0000000gzX0MAI', 'a1SD0000000gzX1MAI', 'a1SD0000000gzX5MAI', 'a1SD0000000gzX6MAI', 'a1SD0000000gzX8MAI', 'a1SD0000000gzXQMAY', 'a1SD0000000gzXSMAY', 'a1SD0000000gzXTMAY', 'a1SD0000000gzXpMAI', 'a1SD0000000gzY5MAI', 'a1SD0000000gzYAMAY', 'a1SD0000000gzYIMAY', 'a1SD0000000gzYJMAY', 'a1SD0000000gzYKMAY', 'a1SD0000000gzYLMAY', 'a1SD0000000gzYPMAY', 'a1SD0000000gzYTMAY', 'a1SD0000000gzYdMAI', 'a1SD0000000gzZBMAY', 'a1SD0000000gzZLMAY', 'a1SD0000000gzZMMAY', 'a1SD0000000gzZNMAY', 'a1SD0000000gzZkMAI', 'a1SD0000000gzZpMAI', 'a1SD0000000gzZqMAI', 'a1SD0000000gza1MAA', 'a1SD0000000gzaLMAQ', 'a1SD0000000gzacMAA', 'a1SD0000000gzapMAA', 'a1SD0000000gzb2MAA', 'a1SD0000000gzb9MAA', 'a1SD0000000gzbIMAQ', 'a1SD0000000gzbJMAQ', 'a1SD0000000gzbKMAQ', 'a1SD0000000gzbgMAA', 'a1SD0000000gzdvMAA', 'a1SD0000000gzeVMAQ', 'a1SD0000000gzebMAA'};

fw1__Payment__c[] payments = new List<fw1__Payment__c>{};
date mydate = date.parse('04/11/2014');
Bank_Account__c BankAccount = [SELECT ID FROM Bank_Account__c WHERE Name = 'Bank Account'];

for(String invoiceId : invoiceIds) {
fw1__Invoice__c i = [SELECT ID, fw1__Account__c, fw1__Contact__r.Id, fw1__Contact__r.Sort_Code__c, fw1__Contact__r.Account_Number__c,  fw1__Contact__r.Bank_Account_Holder__c, fw1__Total_Paid_Amount__c FROM fw1__Invoice__c WHERE ID = :invoiceId];
fw1__Payment__c p = new fw1__Payment__c();
p.fw1__Payment_Method__c = 'Other';
p.fw1__Invoice__c = invoiceId;
p.fw1__Payment_Date__c = mydate;
p.Name = 'Payment for INV-' + invoiceId;
p.fw1__Contact__c = i.fw1__Contact__r.Id;
p.fw1__Amount__c = i.fw1__Total_Paid_Amount__c;
p.fw1__Bank_Aba_Code__c = i.fw1__Contact__r.Sort_Code__c;
p.fw1__Bank_Account_Number__c = i.fw1__Contact__r.Account_Number__c;
p.fw1__Name_On_Account__c = i.fw1__Contact__r.Bank_Account_Holder__c;
p.Bank_Account__c = BankAccount.Id;
p.fw1__Account__c = i.fw1__Account__c;
payments.add(p);
}
PaymentInserter pi = new PaymentInserter(payments);
ID paymentInserterBatchProcessId = Database.executeBatch(pi);

The PaymentInserter looks like this:


global class PaymentInserter implements Database.Batchable<sObject>{
global fw1__Payment__c[] Payments;
global String error {get; set;}

global PaymentInserter(fw1__Payment__c[] p){
  Payments=p;
}

global fw1__Payment__c[] start(Database.BatchableContext info){
  return Payments;
}

global void execute(Database.BatchableContext BC, List<sObject> scope){
        try {
            insert scope;
        } catch (System.CalloutException e){
            error = e.getStackTraceString();
        }     
}

global void finish(Database.BatchableContext BC){
        String body = 'Batch Process has completed. Bacth Job Id was ' + BC.getJobId() + '\n\n';
        if(error != '') {
            body += 'Error = \n\n' + error;
        }
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  mail.setToAddresses(new String[] {'finance@splitthebills.co.uk'});
  mail.setReplyTo('finance@splitthebills.co.uk');
  mail.setSenderDisplayName('Salesforce Apex Batch Process');
  mail.setSubject('Salesforce Apex Batch to Instert Payments has Completed');
        mail.setPlainTextBody(body);
  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

}
Thanks

Andy
Hi everyone,

We have written some code to create objects and insert via Database.executeBatch processes. This has been working fine for a long time, but recently, the inserts have stopped working in certain (unknown) circumstances.

I've created some test code to see if i can find the issue, and all i can find is that if i pass batches of around 30 to Database.executeBatch, they are inserted, but if i pass batches of around 70, these are not inserted. Either way, the batchable process emails us to say there were no errors.

The code that does all this is pretty straightforward and follows the SF rules to avoid running out of SOQL statements, plus the script only creates 2 batches.

Below is the test code that works, but doesn't result in payments being inserted.

Set<Id> invoiceIds = new Set<Id>{'a1SD0000000gzQWMAY', 'a1SD0000000gzQeMAI', 'a1SD0000000gzQiMAI', 'a1SD0000000gzQqMAI', 'a1SD0000000gzTeMAI', 'a1SD0000000gzTjMAI', 'a1SD0000000gzVYMAY', 'a1SD0000000gzVgMAI', 'a1SD0000000gzVhMAI', 'a1SD0000000gzVkMAI', 'a1SD0000000gzVmMAI', 'a1SD0000000gzVpMAI', 'a1SD0000000gzVwMAI', 'a1SD0000000gzVxMAI', 'a1SD0000000gzVzMAI', 'a1SD0000000gzW0MAI', 'a1SD0000000gzWDMAY', 'a1SD0000000gzWMMAY', 'a1SD0000000gzWOMAY', 'a1SD0000000gzWPMAY', 'a1SD0000000gzWSMAY', 'a1SD0000000gzWhMAI', 'a1SD0000000gzWkMAI', 'a1SD0000000gzWwMAI', 'a1SD0000000gzWxMAI', 'a1SD0000000gzX0MAI', 'a1SD0000000gzX1MAI', 'a1SD0000000gzX5MAI', 'a1SD0000000gzX6MAI', 'a1SD0000000gzX8MAI', 'a1SD0000000gzXQMAY', 'a1SD0000000gzXSMAY', 'a1SD0000000gzXTMAY', 'a1SD0000000gzXpMAI', 'a1SD0000000gzY5MAI', 'a1SD0000000gzYAMAY', 'a1SD0000000gzYIMAY', 'a1SD0000000gzYJMAY', 'a1SD0000000gzYKMAY', 'a1SD0000000gzYLMAY', 'a1SD0000000gzYPMAY', 'a1SD0000000gzYTMAY', 'a1SD0000000gzYdMAI', 'a1SD0000000gzZBMAY', 'a1SD0000000gzZLMAY', 'a1SD0000000gzZMMAY', 'a1SD0000000gzZNMAY', 'a1SD0000000gzZkMAI', 'a1SD0000000gzZpMAI', 'a1SD0000000gzZqMAI', 'a1SD0000000gza1MAA', 'a1SD0000000gzaLMAQ', 'a1SD0000000gzacMAA', 'a1SD0000000gzapMAA', 'a1SD0000000gzb2MAA', 'a1SD0000000gzb9MAA', 'a1SD0000000gzbIMAQ', 'a1SD0000000gzbJMAQ', 'a1SD0000000gzbKMAQ', 'a1SD0000000gzbgMAA', 'a1SD0000000gzdvMAA', 'a1SD0000000gzeVMAQ', 'a1SD0000000gzebMAA'};

fw1__Payment__c[] payments = new List<fw1__Payment__c>{};
date mydate = date.parse('04/11/2014');
Bank_Account__c BankAccount = [SELECT ID FROM Bank_Account__c WHERE Name = 'Bank Account'];

for(String invoiceId : invoiceIds) {
fw1__Invoice__c i = [SELECT ID, fw1__Account__c, fw1__Contact__r.Id, fw1__Contact__r.Sort_Code__c, fw1__Contact__r.Account_Number__c,  fw1__Contact__r.Bank_Account_Holder__c, fw1__Total_Paid_Amount__c FROM fw1__Invoice__c WHERE ID = :invoiceId];
fw1__Payment__c p = new fw1__Payment__c();
p.fw1__Payment_Method__c = 'Other';
p.fw1__Invoice__c = invoiceId;
p.fw1__Payment_Date__c = mydate;
p.Name = 'Payment for INV-' + invoiceId;
p.fw1__Contact__c = i.fw1__Contact__r.Id;
p.fw1__Amount__c = i.fw1__Total_Paid_Amount__c;
p.fw1__Bank_Aba_Code__c = i.fw1__Contact__r.Sort_Code__c;
p.fw1__Bank_Account_Number__c = i.fw1__Contact__r.Account_Number__c;
p.fw1__Name_On_Account__c = i.fw1__Contact__r.Bank_Account_Holder__c;
p.Bank_Account__c = BankAccount.Id;
p.fw1__Account__c = i.fw1__Account__c;
payments.add(p);
}
PaymentInserter pi = new PaymentInserter(payments);
ID paymentInserterBatchProcessId = Database.executeBatch(pi);

The PaymentInserter looks like this:


global class PaymentInserter implements Database.Batchable<sObject>{
global fw1__Payment__c[] Payments;
global String error {get; set;}

global PaymentInserter(fw1__Payment__c[] p){
  Payments=p;
}

global fw1__Payment__c[] start(Database.BatchableContext info){
  return Payments;
}

global void execute(Database.BatchableContext BC, List<sObject> scope){
        try {
            insert scope;
        } catch (System.CalloutException e){
            error = e.getStackTraceString();
        }     
}

global void finish(Database.BatchableContext BC){
        String body = 'Batch Process has completed. Bacth Job Id was ' + BC.getJobId() + '\n\n';
        if(error != '') {
            body += 'Error = \n\n' + error;
        }
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  mail.setToAddresses(new String[] {'finance@splitthebills.co.uk'});
  mail.setReplyTo('finance@splitthebills.co.uk');
  mail.setSenderDisplayName('Salesforce Apex Batch Process');
  mail.setSubject('Salesforce Apex Batch to Instert Payments has Completed');
        mail.setPlainTextBody(body);
  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

}
Thanks

Andy
HI,
      IN my Sandbox i have 2 custom objects and 4 standard objects

  the relation ship

 Account--->>contact-->>opp-->>Quote(custom object)-->>quote-line(custom object)-->>Product

 i am planning to move this to production i want move standard objects also, or only custom objects

 i have the following

 3 WFR on Quote + 1 WFR on Quote-line item
 1 trigger on Quote
 1 V.f page is for Quote
 3 webservices
 1 Visualforce template
 
 here quote is parent and line item is child. Quote having roll-up summaries for line-items
can anyone give mesuggestions in which way i want to move above all, first which i want to move
I have a class that I'm using to load data in to the database for my unit tests & I'm trying to populate a Lookup field with some data.

The Lookup field is on a User, and the field is a custom one I added to Product2.

I'm trying to assign the user like this:

  User u = [SELECT Id from User WHERE email = 'stuart.grimshaw@workemail.com'];

  Product2 withTraining = new Product2(Name='Product with Bundled Support & Training', Support_Level__c = 'Silver', Support_Email_Body__c = 'All the things!', Support_Contacts__c = 2, Server_License_Count__c = 5, User_License_Count__c = 15, Product_Type__c = 'Product, Support & Training Bundle');
  withTraining.Trainer__c = u.Id;

or this:

  Product2 withTraining = new Product2(Name='Product with Bundled Support & Training', Support_Level__c = 'Silver', Support_Email_Body__c = 'All the things!', Support_Contacts__c = 2, Server_License_Count__c = 5, User_License_Count__c = 15, Product_Type__c = 'Product, Support & Training Bundle', Trainer__c =u.Id);

or this:

  Product2 withTraining = new Product2(Name='Product with Bundled Support & Training', Support_Level__c = 'Silver', Support_Email_Body__c = 'All the things!', Support_Contacts__c = 2, Server_License_Count__c = 5, User_License_Count__c = 15, Product_Type__c = 'Product, Support & Training Bundle', Trainer__r =u);

None of these things seems to work, when I try and retreive the name of trainer in my test like this:

    public String getTrainerName() {
        if(this.quoteProds == null) {
            this.quoteProds = getQuoteLineItems(this.quoteId);
        }

        for (QuoteLineItem lineItem : this.quoteProds) {
            if(lineItem.PricebookEntry.Product2.Trainer__r.Id  != null) {
                return lineItem.PricebookEntry.Product2.Trainer__r.Name;
            }
        }

        return 'Unknown';
    }

I get 'Unkown'.

Other tests in the suite confirm that the Quote does have line items.