I need to wrap records from Opportunity, Account, Quote, User objects. I need help with Batch Apex execute method. how to retrieve those records and wrap them with the wrapper class on execute method.

In the execute method I don't get data, just get the Id.

global class MyBatchClass implements Database.Batchable<sObject> {
    global Database.QueryLocator start(Database.BatchableContext bc) {
         String query = 'SELECT Id, Account.Name,CreatedBy.LastName,SyncedQuote.Name, Description, Amount, CloseDate, Type FROM Opportunity limit 10';
        return Database.getQueryLocator(query);

    global void execute(Database.BatchableContext bc, List<sObject> records){
        //Just get the Id's nothing else.
        // Need help from records how to retrieved informations. 

    global void finish(Database.BatchableContext bc){
        // execute any post-processing operations

Batch Apex SOQL

FROM Opportunity limit 10

1 Answer 1


In execute method parameter of the records is List<sObject> which is not a concrete SObject, but a general Sobject. In order, to get field values from Opportunity, you can cast SObject to Opportunity and use dot notation to get field value.

public class MyBatchClass implements Database.Batchable<sObject> {
    public Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator([SELECT Id, Account.Name, CreatedBy.LastName, SyncedQuote.Name, Description, Amount, CloseDate, Type FROM Opportunity LIMIT 10]);

    public void execute(Database.BatchableContext bc, List<SObject> records){
        for(SObject record :records){
            Opportunity opp = (Opportunity) record;
            System.debug('Account.Name: ' + opp.Account.Name);
            System.debug('CreatedBy.LastName: ' + opp.CreatedBy.LastName);

    public void finish(Database.BatchableContext bc){

I've also done the following improvements to your code:

  • public access modifier instead of the global. global is used in a managed package to make elements accessible outside of the namespace
  • move SOQL query from string to SOQL expression. Allows to detect problems with query during compilation
  • 2
    Also, in general, you could change records as the parameter to just List<Opportunity>.
    – sfdcfox
    Sep 17, 2021 at 8:09
  • 1
    Just one minor comment: global access does do what you said, but actually makes the class visible across namespace boundaries. You must use global, for example, to expose a subscriber class so it can be instantiated and invoked within an installed managed package too. Similarly for exposing a class from one managed package to another managed package, etc.
    – Phil W
    Sep 17, 2021 at 10:08

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.