I already successfully collecting the list of data from callout another system as json body to the inner class to accomodate custom information:

Here is the apex class of the inner class:

public class InvoiceHeaderListController {

    public class ResponseData {
        public List<InvoiceData> receivableInvoices{get;set;}
        public String lastRowNum{get;set;}
        public Boolean hasNext{get;set;}

    public class InvoiceData {
        public String id{get;set;}
        public BusinessPartnerData businessPartner{get;set;}
        public String invoiceNumber{get;set;}
        public String invoiceAmount{get;set;}
        public Datetime invoiceDate{get;set;}
        public Datetime dueDate{get;set;}
        public String invoiceStatus{get;set;}
        public Boolean isCarriedOver{get;set;}
        public Datetime paymentDate{get;set;}
        public String contractingEntity{get;set;}
        public String settlement{get;set;}
        public ReferenceData reference{get;set;}
        public List<ChargeData> charges{get;set;}

    public class BusinessPartnerData {
        public String id{get;set;}
        public String name{get;set;}
        public String country{get;set;}
        public ReferenceBPData reference{get;set;}

    public class ReferenceBPData {
        public String teraHotelId{get;set;}
        public String legalCountryIdISOAlpha2{get;set;}

    public class ReferenceData {
        public String paymentOutId{get;set;}
        public String teraHotelId{get;set;}
        public String businessUnit{get;set;}

    public class ChargeData {
        public String chargeId{get;set;}
        public String chargeTypeName{get;set;}
        public String chargeBaseAmount{get;set;}
        public String chargePercentage{get;set;}
        public String chargeFixedAmount{get;set;}
        public String chargeTotalAmount{get;set;}

    public String getFromAnotherSystem() {
        //do callout

    public List<InvoiceData> getInvoiceHeaderRows(ResponseData rd) {
        List<InvoiceData> resultList = rd.receivableInvoices;
        return resultList;

    //get the response as json body
    String responseString = getFromAnotherSystem();

    //get the data and map to inner class
    ResponseData rData = (InvoiceHeaderListController.ResponseData) JSON.deserialize(responseString, InvoiceHeaderListController.ResponseData.class);
    List<InvoiceData> invoiceDataList = getInvoiceHeaderRows(rData);

    //do apex batch using inner class
    InvoiceHeaderBatch ihBatch = new InvoiceHeaderBatch(invoiceDataList);
    Database.executeBatch(ihBatch, 100);

And then when I create the apex batch:

global class InvoiceHeaderBatch implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts {
    global List<InvoiceHeaderListController.InvoiceData> invoiceDataList = new List<InvoiceHeaderListController.InvoiceData>();

    global InvoiceHeaderBatch(List<InvoiceHeaderListController.InvoiceData> invDataList) {
        this.invoiceDataList = invDataList;

    global System.Iterable<sObject> start(Database.BatchableContext bc) {
        return this.invoiceDataList;

    global void execute(Database.BatchableContext bc, List<InvoiceHeaderListController.InvoiceData> scope) {


    global void finish(Database.BatchableContext bc) {


I'm getting compile error:

global methods do not support parameter type of List<InvoiceHeaderListController.InvoiceData>

Do I have to create unnecessary custom object only to store this custom information as the apex batch does not support inner class? Or I'm missing something?


I modify the visibility of the inner class to global

public global InvoiceHeaderListController {

    global class ResponseData {
        public List<InvoiceData> receivableInvoices{get;set;}
        public String lastRowNum{get;set;}
        public Boolean hasNext{get;set;}

Now I'm getting the compile error:

Class InvoiceHeaderBatch must implement the method: void Database.Batchable<SObject>.execute(Database.BatchableContext, List<SObject>)

Why my inner class identified as non sObject class?

1 Answer 1


You are using Custom Iterator. So you need to implement same as well.

InvoiceHeaderBatch implements Database.Batchable<InvoiceHeaderListController.InvoiceData>

Here is a complete code sample for you.

public with sharing class SimpleBatchApex implements Database.Batchable<String>
    public Iterable<String> start(Database.BatchableContext BC)
        return new List<String> { 'Do something', 'Do something else', 'And something more' };

    public void execute(Database.BatchableContext info, List<String> strings)
        // Do something really expensive with the string!
        String myString = strings[0];

    public void finish(Database.BatchableContext info) { }


  • 1
    I see. So the Database.Batchable must be specifically declared as custom inner class
    – Rival
    Jul 16, 2018 at 4:26
  • @Rival yup. we need to do that. Jul 16, 2018 at 4:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.