2013-02-18 58 views
1

之前,我有一个批次类有未提交的待处理工作。请提交或回滚呼叫

public class BatchCreateGCalendars implements Database.Batchable<SObject>, Database.Stateful, Database.AllowsCallouts { 

     private String query; 
     private String pageToken ; 
     private String accessToken; 
     private String CalendarId; 

     public BatchCreateGCalendars(){ 

      this.query = 'Select Id, Name, CalendarId__c from CalendarSettings__c'; // Query to get the CalendardID (Google ID) 

     } 

     public Database.Querylocator start(Database.BatchableContext BC){ 

      return Database.getQueryLocator(query); 

     } 

     public void execute(Database.BatchableContext BC, List<sObject> scope){ 

      GoogleForce__c gApp   = GoogleForce__c.getAll().values()[0];   
      GCalendarUtil.Calendar cal = new GCalendarUtil.Calendar(); 
      GCalendarUtil.GResponse gResp = new GCalendarUtil.GResponse(); 


      String endPoint = GCalendarUtil.CALENDAR_BASE + GCalendarUtil.CAL_URL; // Calendar Endpoint 

      // Iterate over the records, delete each calendar and create the calendar again. 

      for(CalendarSettings__c c : (List<CalendarSettings__c>)scope){ 



       String delEndpoint = endpoint + '/' + c.CalendarId__c; 

       if(gApp.ExpiresIn__c < system.now()){ 
        gResp    = GCalendarUtil.getNewToken(gApp); 
        accessToken   = gResp.access_token; 
        gApp.AccessToken__c = gResp.access_token; 
        gApp.ExpiresIn__c = System.now().addSeconds(gResp.expires_in); 

       }else{ 
        accessToken = gApp.AccessToken__c; 
        System.debug('Calendar Id is '+ c.CalendarId__c); 
       } 
       String re= GCalendarUtil.doApiCall(null,'GET','https://www.googleapis.com/calendar/v3/calendars/'+c.CalendarId__c+'/events',accessToken); 

      re = re.replaceAll('"end":','"end1":'); 
    re = re.replaceAll('"dateTime":','"dateTime1":'); 
       System.debug('response is' +re); 
       JSON2Apex1 aa = JSON2Apex1.parse(re); 

       List<JSON2Apex1.Items> ii = aa.items ; 
         System.debug('next token is'+ aa.nextPageToken); 
       List<String> event_id =new List<String>(); 
       if(ii!= null){ 
       for(JSON2Apex1.Items i: ii){ 
       event_id.add(i.id); 
       } 
       } 
      for(String s:event_id) 
      {GCalendarUtil.doApiCall(null,'DELETE','https://www.googleapis.com/calendar/v3/calendars/'+c.CalendarId__c+'/events/'+s,accessToken); 

      } 
     pageToken = aa.nextPageToken; 
     CalendarId=c.CalendarId__c; 

       if(pageToken!=null) 
       deleteEvents(accessToken , pageToken,c.CalendarId__c); 

      } 

      update gApp; 
     } 

     /* 
      After the batch job is finished, trigger the other batch jobs where the Campaigns are sent as Events to the calendars. 
      Use the CalendarQuery field on the each calendarSettings record. 
     */ 

     public void finish(Database.BatchableContext BC){ 

     BatchDeleteEvents bjob1 = new BatchDeleteEvents(CalendarId,accessToken); 
       Database.executeBatch(bjob1,9); 


      for(CalendarSettings__c c : [Select Id, Name, CalendarQuery__c, CalendarId__c,FieldToDisplay__c from CalendarSettings__c WHERE Name IN ('Public Calendar', 'Internal marketing Calendar')]){ 

       BatchPublicCampaignsToGoogle bjob = new BatchPublicCampaignsToGoogle(c.CalendarQuery__c,c.CalendarId__c,c.FieldToDisplay__c); 
       Database.executeBatch(bjob,9); // This is set to process 9 records, allowing 1 extra callout for refresh token in case needed. 

      } 


     } 

     public static void deleteEvents(String accessToken,String pageToken,String CalendarId){ 
     List<Event__c> event_id =new List<Event__c>(); 

     while(pageToken != null) 
    { String re = GCalendarUtil.doApiCall(null,'GET','https://www.googleapis.com/calendar/v3/calendars/'+CalendarId+'/events?pageToken='+pageToken,accessToken); 
        System.debug('next page response is'+ re); 
        re = re.replaceAll('"end":','"end1":'); 
    re = re.replaceAll('"dateTime":','"dateTime1":'); 
     JSON2Apex1 aa = JSON2Apex1.parse(re); 
     List<JSON2Apex1.Items> ii = aa.items ; 
     System.debug('size of ii'+ii.size()); 
     pageToken = aa.nextPageToken ; 

       if(ii!= null){ 
       for(JSON2Apex1.Items i: ii){ 
       event_id.add(new Event__c(name = i.id)); 
       } 
       } 



    } 
    insert event_id; 


     } 

    } 

在这段代码我在这行得到错误

String re= GCalendarUtil.doApiCall(null,'GET','https://www.googleapis.com/calendar/v3/calendars/'+c.CalendarId__c+'/events',accessToken); 

误差

You have uncommitted work pending. Please commit or rollback before calling out 

为什么我面对这个错误请帮助和更多的疑问是当我在完成方法中调用此代码

BatchDeleteEvents bjob1 = new BatchDeleteEvents(CalendarId,accessToken); 
        Database.executeBatch(bjob1,9); 

将同步呐执行此代码意味着一批9所处理的所有对象,然后控制就会来到这个代码

BatchPublicCampaignsToGoogle bjob = new BatchPublicCampaignsToGoogle(c.CalendarQuery__c,c.CalendarId__c,c.FieldToDisplay__c); 
        Database.executeBatch(bjob,9); 
+2

嗨Ritesh!恐怕我没有其他答案,比我从http://stackoverflow.com/questions/14545072/unexpected-null-pointer-exception-in-testing发表的评论。你必须重新排列它们。首先标注,然后DML(插入,更新等)。或者DML +'@ future',所以标注出现在不同的上下文中(然后,如果标注失败,则需要弄清楚如何处理插入的数据)。甚至没有'Database.setSavepoint()'会帮助你。 – eyescream 2013-02-18 14:48:31

+0

只是仔细看看代码时,我注释掉从执行调用deleteEvents函数,然后没有错误,但如此调用deleteEvents函数导致error.but在该函数中,我首先调用callouts然后插入它并执行最后一个语句'更新gApp;'不是DML语句gApp是自定义设置,当我忽略它仍然得到相同的错误。什么是错误的deleteEvent函数我首先标注api,然后插入按规则仍然收到错误 – 2013-02-18 16:07:42

+0

@eyescream请回复,如果我跟随规则为什么我得到错误? – 2013-02-18 16:08:24

回答

0

你不能在Salesforce /顶点标注与DML语句一起。

您可以首先根据标注状态执行CallOut,然后您可以调用DML统计信息。