0

I have an Apex Class that retrieves an aggregate result of Contacts per Accounts in order to validate a maximum of 2 Contacts of a certain type.

I have tried several things. First I used a set and passed in all Account ids, but I got no results. Then I built the query in a string and also got no results. But if I run the query in the developer console query editor I do get the results I expect. Why does my query not work in Apex?

Apex:

public static map<id,String> beforeInsertHandler (Contact[] consList) {
    //create a map of errors per contact and return at and of method if any entry added
    map<id,String> exceptionsMap = new map<id,String>();

    //get map of all principals per account being inserted
    map<id,Contact> ContactsMap = new map<id,Contact>();
    set <String> accIds = new set<String>();
    for(Contact con:consList){
        if(con.loan__Contact_Type__c == 'Principal' && con.Active__c==true){
            ContactsMap.put(con.AccountId,con);
            system.debug('### adding contact accIds: ' + accIds);
            accIds.add(con.AccountId);
        }
    }

    String query = 'Select count(id) cnt, AccountId  From Contact where AccountId IN (\'';
    for(String accid: accIds){
        query+= accId + '\',';
    }
    String aggQuery = query.left(query.length()-1);  

    aggQuery += ') AND Active__c=true AND loan__contact_Type__c= \'Principal\' group by AccountId';

    AggregateResult[] ars= database.query(aggQuery);
    //THE QUERY ABOVE RETURNS 0 RECORDS WHEN I HAVE INSTERTED SEVERAL CONTACTS THAT MEET THE CRITERIA

    //get aggregate count of principals per account and validate if active principals count is greater than 2        
    for(AggregateResult ar:ars) {
        system.debug('### aggregate contacts:' + ar);
        integer principalCnt = (integer)ar.get('cnt');
        string accId = (string)ar.get('AccountId');

        if(principalCnt >=2 && ContactsMap.containsKey(accId)) {
            for(Contact con: consList) {
                if(accId == con.AccountId) {
                    exceptionsMap.put(con.id,'The Account for this Contact already contains the maximum allowed of 2 active Principals.');
                }
            }
        }   
    }
}
3
  • 1
    Your code does not even have a return statement and hence won't compile.
    – Adrian Larson
    Aug 25, 2015 at 5:32
  • Also please post your working SOQL verbatim.
    – Adrian Larson
    Aug 25, 2015 at 5:33
  • Also, are you sure the code that calls this method is passing in a collection that contains elements to begin with and you're not passing in an empty List<Contact>?
    – Adrian Larson
    Aug 25, 2015 at 5:36

1 Answer 1

1

looking at the method name, it seems the method is being called from a before insert event on contact object.

if that's the case, the query will not get the contacts you are currently inserting. (since you are running it before the records are inserted)

if you change that to after insert its should work.

1
  • The issue was in fact the before insert event as Vamsi Krishna stated. once I updated that the code worked perfect. I am sorry if the code was a bit vague as it did have a return statement ONLY if exceptionsMap was not empty, but I may have accidentally removed that when removing sensitive data, also the list being passed was always populated as it was coming from a trigger.new on an insert trigger. the final version went back to just using the query in a for loop for the aggregateresult object instead of building the query string and passing it to database.query as per this code.
    – Mauricio
    Aug 26, 2015 at 7:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .