0

I have created a wrapper class in which I have Name and Rating variables which are string type.

1)I have pulled out Account with the name and Rating and wrapped it in a wrapper class and stored the object as a key in the map which is of type class AccountWrap.

Map<AccountWrap,Account>MapbyObject=new Map<AccountWrap,Account>();

2)Then I pulled account record from the trigger.new list and looped through,while looping I pulled out the Account name and rating and wrapped them in the wrapper class and passed it to the map to check if the map has key which matches the object's Name and rating.

AccountWrap accwr=new AccountWrap(acc.name,acc.rating);

Account acc20=MapbyObject.get(accwr);

I was hoping that map will match the key which I passed and it will return Account asscoiated with the key which means it is a duplicate record and then I will show an error to the user.

However,I am always getting null values. I have a before insert trigger in which I am calling class and it's method.

Here is the code:-

    public class AccTrigger {
        Map<AccountWrap, Account> MapbyObject = new Map<AccountWrap, Account>();
        public void CompareRecords(list<account> AccRecords) {
            for (Account rec : [
                SELECT name, rating
                FROM Account
                WHERE name = 'james constructions'
                LIMIT 1
            ]) {
                AccountWrap acwrap = new AccountWrap(rec.name, rec.rating);
                MapbyObject.put(acwrap, rec);
                System.debug('The map has the following values' + MapbyObject);
                //The map has the following values{AccountWrap:[Name=james constructions, Rating=Warm]=Account:
                // {
                // Name=james constructions, Rating=Warm, Id=0015e000003lp6rAAA}}
                // }

                for (Account acc : AccRecords) {
                    System.debug('The account has the following record' + acc);
                    AccountWrap accwr = new AccountWrap(acc.name, acc.rating);
                    System.debug('the accountwrap has' + accwr);
                    //The accountwrap hasAccountWrap:[Name=james construction, Rating=Warm]
                    Account acc20 = MapbyObject.get(accwr);
                    //Here I am only getting null value when I was expecting non null value;
                    System.debug('The map has the follogin values' + acc20);
                    if (acc20 != null) {
                        acc.adderror('dupe');
                    }
                }
            }
        }
        public class AccountWrap {
            public String Name;
            public String Rating;
            public AccountWrap(String name, string rating) {
                System.debug('I am in the wrapper class constructor');
                this.name = name;
                this.rating = rating;
            }
        }
    }
1

2 Answers 2

1

You need to read Using Custom Types in Map Keys and Sets for how to use a custom wrapper as key in a Map. However, there's an easier way; just use the Account object itself. Here's how to remove the AccountWrap entirely:

    public class AccTrigger {
        Map<Account, Account> MapbyObject = new Map<Account, Account>();
        public void CompareRecords(list<account> AccRecords) {
            for (Account rec : [
                SELECT name, rating
                FROM Account
                WHERE name = 'james constructions'
                LIMIT 1
            ]) {
                Account key = new Account(Name=rec.name, Rating=rec.rating);
                MapbyObject.put(key, rec);
            }
            System.debug('The map has the following values' + MapbyObject);
            for (Account acc : AccRecords) {
                System.debug('The account has the following record' + acc);
                Account key = new Account(Name=acc.name, Rating=acc.rating);
                System.debug('the accountwrap has' + key);
                //The accountwrap hasAccountWrap:[Name=james construction, Rating=Warm]
                Account acc20 = MapbyObject.get(key);
                System.debug('The map has the follogin values' + acc20);
                if (acc20 != null) {
                    acc.adderror('dupe');
                }
            }
        }
    }

This is my preferred method for using keys to match records, when possible. It's far more efficient, code-wise, and I don't need to invent custom hash algorithms every time. I've left most of the spelling problems, etc, here, just to give you an idea of where things are relative to what you wrote.

One important thing, though, always remember to not nest your loops together; your map is technically incomplete in your original code, while this code populates the map first, then checks the results later.

3
  • I agree. Why create your own class and supporting methods if you can leverage the methods built into Salesforce's own Account object?
    – dwestgate
    May 2, 2021 at 4:05
  • @sfdcfox,@dwestgate.Thanks for your suggestions...My code with the wrapper class is working fine but I will implement what Sfdcfox has suggested as I want to keep things simple....Thanks to all once again
    – nit
    May 3, 2021 at 17:06
  • So I went to use this trick today and I found the limitation: it doesn’t work for situations where you need to include a formula field.
    – dwestgate
    May 4, 2021 at 2:00
0

Apex doesn't know how to hash your AccountWrap custom class or determine when two instances are equal. Add the required methods:

public class AccountWrap {
    public String name;
    public String rating;
        
    public AccountWrap(String name, String rating) {
        System.debug('I am in the wrapper class constructor');
        this.name = name;
        this.rating = rating;
    }
    
    public Boolean equals(Object obj) {
        final AccountWrap accountWrapObj = (AccountWrap) obj;
        return this.name.equals(accountWrapObj.name);
    }
    
    public Integer hashCode() {
        return this.name.hashCode();
    }
}

Documentation is here: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm

You must log in to answer this question.

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