SOQL issue when querying ActivityHi history as a subquery.

I am querying an ActivityHistory, and it seems that you can only query it as a SUBQUERY object against some other object. This is great - I changed my request to the request of the Account object, and the ActivityHistory in the subquery. It seemed to be working fine. But when testing, I discovered a case where the ActivityHistory subquery returned more than 200 results. I started getting this error:

  FATAL_ERROR | System.QueryException: entity type ActivityHistory does not support query 

... in debug logs. This is apparently only a problem when an account has more than 199 related records in an ActivityHistory. To make sure this was the reason, I tried putting the LIMIT 199 and the LIMIT 200 clause in a subquery. Of course, when I use 199 (or something less), it works fine. Using 200 (or something more) results in the error above.

My code is below. It should be noted that the request is in a FOR loop. One theory that I have regarding why it creates an error for large values โ€‹โ€‹of the LIMIT clause is that maybe 200 is the point at which the FOR loop executes a batch request into separate fragments - maybe the second fragment does not qualify as a "subquery" (because it works separately?) - and SalesForce doesn't like that.

Oh, and one more thing: the same code seems to work fine in the Apex Anonymous editor (although I had to make a few changes - replacing the built-in variables with explicit values). It is strange that the announcement editor is completely happy with this, but SFDC servers do not like it.

Anyway, I'm going to make a few more problems. Does anyone have any ideas?

Thanks!

the code:

  // ActivityHistory on Account
     for (Account a: [// you can't query ActivityHistory directly; only in a subquery against another object type
         SELECT
              Id
             , Name
             , (SELECT
                     ActivityDate
                    , ActivityType
                    , CRM_Meeting_Type__c
                    , Description
                    , CreatedBy.Name
                    Status
                    WhatId
                 FROM ActivityHistories
                 WHERE ActivityType IN: included_activity_history_types
                 // LIMIT 200
             )
         FROM Account WHERE Id =: accountId
     ]) {
      for (ActivityHistory ah: a.ActivityHistories) {
         if (ah.WhatId == null) {continue;  } // skip adding activities without a WhatId

         if (((string) ah.WhatId) .startsWith ('001')) {// only add ActivityHistory tied directly to an Account (the query above pulls back all ActivityHistory on related Oppty as well)
             activities.add (new ActivityWrapper (ah));
         }
      }
     }
+6
source share
2 answers

Great question; I'm not quite sure why it will work in Execute Anonymous, but not in your Apex class.

However, I have some recommendations. I found it useful to separate SOQL queries from a for loop, and then use the getSObjects method to get the subquery data that was returned. Using this method, I successfully retrieved over 200 ActivityHistory entries in the Apex class.

Note: one difference (between your code and the previous way I got this action) is that I did not filter the ActivityType in the ActivityHistories WHERE clause. So, if the code below generates the same error, I would check the following.

 List<Account> AccountsWithActivityHistories = [ // you can't query ActivityHistory directly; only in a subquery against another object type SELECT Id ,Name ,( SELECT ActivityDate ,ActivityType ,CRM_Meeting_Type__c ,Description ,CreatedBy.Name ,Status ,WhatId FROM ActivityHistories WHERE ActivityType IN :included_activity_history_types //LIMIT 200 ) FROM Account WHERE Id = :accountId ]; // ActivityHistories on Account for (Account a : AccountsWithActivityHistories) { for (ActivityHistory ah : a.getSObjects('ActivityHistories')) { // skip adding activities without a WhatId if ( ah.WhatId==null ) { continue; } if (((string)ah.WhatId).startsWith('001')) { // only add ActivityHistory tied directly to an Account // (the query above pulls back all ActivityHistory on related Oppty as well) activities.add(new ActivityWrapper(ah)); } } } 
+7
source

It may be outdated, but I got into this problem and wanted to drop my solution there, which I found on another forum.

An activityhistory object is simply a Task or Event set to Closed. Therefore, you can request the object that is behind the "Activity History", and attach it under a new contact or lead, and it will save the same object as the new object "Activity History".

 list<Task> activityHistory = [SELECT Id,WhoId FROM Task t WHERE t.WhoId = 'randomID' and t.Status != 'Open']; for(Task currentAH : activityHistory){ system.debug(currentAH.Id); } 

The above code returns all the objects of the Task event history and allows me to reuse them using WhoId for another contact / guide.

+1
source

Source: https://habr.com/ru/post/917565/


All Articles