I am running into the infamous System.LimitException: Too many SOQL queries: 201 error, but I am really not sure why. In this class I am attempting to get a JSON object from a URL and then use it to create new contacts in our system. In my class I need to continue to call makeHttpCall until next_url is returned null to get the entire JSON object. Once that is done I want to call processData to insert the new contacts.
I am attempting to query a list from a map and am hitting the limit when I do so.
Line 102 - Contact[] conList = [SELECT ID, Email, Zenefits_Id__c FROM Contact WHERE Zenefits_Id__c IN : newEmployeeMap.keySet() LIMIT 200];
But I am also receiving the error from...
line line 12 where I call processData();
Here is my code for reference. I have removed the initial URL as well as the Bearer token for security purposes.
public class zenefitsEmployeeSync implements Schedulable, Database.AllowsCallouts {
public void execute(SchedulableContext SC) {
makeCallout();
}
@future(callout = true)
public static void makeCallout() {
string url = 'xxxxxxxxxxxxxxxxxxx';
do {
url = makeHttpCall(url);
} while(url != null);
processData();
}
static list<object> newEmployees = new list<object>();
static map<String,Id> dataAttributes = new Map<string,Id>();
static List<Object> account = new List<Object>();
static {
for (account a : [SELECT Id, Name FROM Account WHERE Name Like 'LLC%' LIMIT 1]) {
dataAttributes.put('accountId',a.Id);
}
}
static List<Object> Calendar = new List<Object>();
static {
for (pse__Work_Calendar__c workCal : [SELECT name, ID FROM pse__Work_Calendar__c WHERE Name Like 'US Full-Time 8x5%' LIMIT 1]) {
dataAttributes.put('workcalId',workCal.Id);
}
}
public static String makeHttpCall(String url) {
string nextUrl;
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setHeader('Authorization', 'Bearer xxxxxxxxxx');
request.setEndpoint(url);
request.setMethod('GET');
HttpResponse response = http.send(request);
// If the request is successful, parse the JSON response.
if (response.getStatusCode() == 200) {
// Deserializes the JSON string into collections of posts.
Map<String, Object> wrapper = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
if (wrapper.containsKey('data')) {
Map<String, Object> wrapper2 = (Map<String, Object>) wrapper.get('data');
if (wrapper2.containsKey('data')) {
nextUrl = (String) wrapper2.get('next_url');
newEmployees.addAll((List<Object>)wrapper2.get('data'));
system.debug('New Employees Sze ' + newEmployees.size());
}
}
}
return nextUrl;
}
public static void processData() {
List<contact> employeesToInsert = new List<contact> ();
Map<String,map<String, Object>> employeeMap = new Map<String,map<String, Object>>();
for (Object LevvelEmployee : newEmployees) {
Map<string,object> employees = (Map<string,object>)LevvelEmployee ;
Map<String,map<String, Object>> newEmployeeMap = new Map<String,map<String, Object>>();
Map<String, Object> managerWrapper = (Map<String, Object>) Employees.get('manager');
Map<String, Object> DepartmentWrapper = (Map<String, Object>) Employees.get('department');
Map<String,Object> empValues = new Map<String,Object>();
if( (Employees.get('status') == 'active')&&( managerWrapper.get('url') != NULL)){
String ZenefitsLastName = (String) Employees.get('last_name');
empValues.put('LastName',Employees.get('last_name'));
String ZenefitsFirstName = (String) Employees.get('first_name');
empValues.put('FirstName',Employees.get('first_name'));
String ZenefitseEmployeeId = (String) Employees.get('id');
empValues.put('ZenefitseEmployeeId',Employees.get('id'));
String ZenefitsEmail = (String) Employees.get('work_email');
empValues.put('ZenefitsEmail',Employees.get('work_email'));
String Status = (String) Employees.get('status');
empValues.put('Status',Employees.get('status'));
String title = (String) Employees.get('title');
empValues.put('title',Employees.get('title'));
String phoneNumber = (string) employees.get('work_phone');
empValues.put('phoneNumber',Employees.get('work_phone'));
string managerUrl = (string) managerWrapper.get('url');
empValues.put('managerUrl',managerWrapper.get('url'));
system.debug('managerURL ' + managerWrapper.get('url'));
string managerId = managerUrl.substring(managerUrl.length() - 7, managerUrl.length() - 0);
empValues.put('managerId',managerId);
string alias = ZenefitsFirstName.substring(0,1) + ZenefitsLastName.substring(0,3);
system.debug('alias ' + alias);
empValues.put('alias', alias);
string department = (string) departmentWrapper.get('url');
empValues.put('department',departmentWrapper.get('url'));
String departmentURL = department.substring(department.length() - 6, department.length() - 0);
empValues.put('departmentURL',departmentURL);
system.debug('department url ' + departmentURL);
newEmployeeMap.put(ZenefitseEmployeeId, empValues);
system.debug('newEmployeeMap ' + newEmployeeMap);
//now query the list of contacts in the system so we can remove them and only insert new Employees
Contact[] conList = [SELECT ID, Email, Zenefits_Id__c FROM Contact WHERE Zenefits_Id__c IN : newEmployeeMap.keySet() LIMIT 200];
system.debug('conList ' + conList);
for(Contact con1 : conList)
{
//remove the Employees that already exist in the system
newEmployeeMap.remove(con1.Zenefits_Id__c); //remove existing contacts
system.debug('newEmployeeMap ' + newEmployeeMap);
}
for(String zId: newEmployeeMap.keyset())
{
map<String,Object> currMap = newEmployeeMap.get(zId);
system.debug('currMap' + currMap);
//create a contact record for the new resource
Contact con = new Contact();
con.Zenefits_Id__c = (string)currMap.get('ZenefitseEmployeeId');
con.Lastname = (string)currMap.get('LastName');
con.FirstName = (string)currMap.get('FirstName');
con.Email = (string)currMap.get('ZenefitsEmail');
con.Title = (string)currMap.get('title');
con.Manager_Zenefits_ID__c = (string)currMap.get('managerId');
con.Phone = (string)currMap.get('phoneNumber');
con.pse__Start_Date__c = system.today();
con.pse__Is_Resource__c = true;
con.pse__Is_Resource_Active__c = true;
con.AccountId = (String)dataAttributes.get('accountId');
con.pse__Work_Calendar__c = (String)dataAttributes.get('workcalId');
con.pse__Level__c = 'Consultant';
con.pse__Resource_Role__c = 'Analyst';
con.recordTypeId = '0121N0000012es9QAA';
con.zenefits_department_id__c = departmentURL;
con.alias__c = (String)currmap.get('alias');
employeesToInsert.add(con);
system.debug('contacts to update ' + employeesToInsert.size());
}
}
upsert employeesToInsert;
}
}
}
Contact[] conList = [SELECT ID, Email, Zenefits_Id__c FROM Contact WHERE Zenefits_Id__c IN : newEmployeeMap.keySet() LIMIT 200];
.May be yournewEmployees
is more. You can query this on top and use it inside.