0

I have a class that calls to an apex method with in a for loop and that method in-turn calls other apex method. All the methods have SOQL's in them.

Running into 101 SOQL issue.

for(sobject obj:somelist) {
    apexclass1.mehtod1(obj);
}

public class apexclass1 {
    public void method1(obj) {
        List<Sobject> queryresults = [select id from sobject where id=:obj.Id];
        apexclass2.method2(queryresults.Id);
    }
}

public class apexclass2 {
    public void method2(Id) {
        List<Sobject> queryresults = [select id from sobject where id=:Id];
    }
}

I tried to bulkify the methods by eliminating loops and passing list<> instead of single record to methods. But I might end-up disturbing existing functionality somewhere.

What would be the better and safe approach now?

  • 2
    It looks as though you may need to try to refactor this in some manner so that you can utilize a SOQL for loop. Since I don't know what these do or what you're trying to accomplish, that's about the only advice I can provide. – crmprogdev May 5 '16 at 20:06
  • 2
    I'm afraid changing/adding code that deals with collections instead of single IDs or single objects is usually necessary. If you have unit tests then they will give you some protection (though will need changing too - you can start by passing the single object your tests probably already have wrapped in lists or sets). – Keith C May 5 '16 at 20:07
  • 1
    if you think these methods might be called from other code you don't know about, you can do a search for that method name within your IDE project src folder. – Jeremy Nottingham May 5 '16 at 20:22
2

Collection are best way to avoid these situations. With minimum changes you can avoid SOQL query by bulkify as below:

Set<Id> objIDSet = new Set<Id>();
for(sobject obj:somelist )
{
    objIDSet.add(obj.id);   
}
apexclass1.mehtod1(objIDSet);


public class apexclass1
{
    public void method1(Set<Id> objIds)
    {
        Set<Id> queryresults = new Set<Id>();
        for(Sobject queryresult : [select id from sobject where id in: objIds])
        {
            queryresults.add(queryresult.Id);
        }
        apexclass2.method2(queryresults);
    }
}

public class apexclass2
{
    public void method2(Set<Id> recordIDs)
    {
        List<Sobject> queryresults = [select id from sobject where id in:recordIDs];

    }
}

However, above code has chain of for-loops. To avoid this you would change the class design. With this design above is solution.

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.