+ Start a Discussion
stoutstreetstoutstreet 

Map Always returning Null

Hi, Can't seem to figure out as to why this piece of code always returns a Null value and always executes the if statement even when there is an entry in the table. Thanks


                   if (currentBuyerId.get(a.UserOrGroupId) == NULL){
                    //If UserOrGroupId does not exist
                    //Add records being shared with buyers into the array for later insert
                    relationShare.add(buyerShare);      
                }

 

**********************

 

trigger Buyer_Supplier_Share on mcbangalore__Relation__c (after insert,after update) {

AccountShare buyerShare = new AccountShare();
List<AccountShare> relationshare = new List<AccountShare>();
id badId = '00550000001DzCR';

//
if ( trigger.isInsert||trigger.isUpdate) {

    for(Relation__c relation:trigger.new) {
        
        //Retrieve every supplier sharing record and insert it into the Buyer Sharing table
        
         List<AccountShare> supplierShare= [Select AccountId, UserOrGroupId from AccountShare
                        where AccountId =:relation.Supplier__c];

        //Map the Ids and UserOrGroup Ids of the Buyer Record to prevent duplicate entries
    
        Map<Id, AccountShare> currentBuyerId = new Map<Id,AccountShare> ([Select UserOrGroupId,AccountId from AccountShare
                        where AccountId = :relation.Buyer__c]);
        
        for (AccountShare a :supplierShare) {   
        
            //Share the Buyer Account with the Sellers;
            buyerShare.AccountId = relation.Buyer__c;
            //Share the Seller Account with all the Buyer Contacts
            buyerShare.UserOrGroupId = a.UserorGroupId;
            
            //Set the access level
            buyerShare.AccountAccessLevel = 'edit';
            //Set the Sharing Reason
            //buyerShare.RowCause = schema.Relation__Share.Rowcause.Grant_Relationship__c;
        
            //Check if the UserOrGroupId already exists for this Id
                
                   if (currentBuyerId.get(a.UserOrGroupId) == NULL){
                    //If UserOrGroupId does not exist
                    //Add records being shared with buyers into the array for later insert
                    relationShare.add(buyerShare);      
                }

    
            } //For AccountShare a
        } //for trigger.new
    } //If (trigger.IsInsert)


//Insert Array into the database
Database.SaveResult[] buyerresult = Database.insert(relationShare,false);

//Process Errors

dnakonidnakoni

See this query:

Map<Id, AccountShare> currentBuyerId = new Map<Id,AccountShare> ([Select UserOrGroupId,AccountId from AccountShare

created a map of AccountShare.Id -> AccountShare, so the AccountShare.Id is the key here, but later on you're trying to get back the AccountShare by passing in the UserOrGroupId as the key.

It doesn't matter that in the query you specify UserOrGroupId as the first field, the map will always be created using the record ID. To fix this, first do a query into a List, and loop over that list to create your map of

UserOrGroupId -> AccountShare

 

Good luck!

sfdcfoxsfdcfox

No, the map does contain null values for that UserOrGroupId field; the branching logic is happening correctly.

 

However, there are a number of problems with your code, which I shall outline.

 

 

if ( trigger.isInsert||trigger.isUpdate) {

Your trigger only runs on insert and update. This if statement isn't necessary and will probably confuse the next developer to come along. Comment why you did it this way, or remove it. I realize your code is a work in progress, but you shouldn't leave something like this in there without a comment of some sort.

 

 

for(Relation__c relation:trigger.new) {

This loop appears fine, but note that you're running queries INSIDE this loop. That is never a good idea, as the first time someone tries to use the data loader or import wizard, or the first time you go to create a Visualforce page that uses this trigger, you might run into query limits. Instead, use a "MAP" to load the entire set of data in at once, and then iterate through that map using ID values as you go along. However, in this case, you can skip using a map and so on because of my next point.

 

 

//Map the Ids and UserOrGroup Ids of the Buyer Record to prevent duplicate entries

This whole logic here isn't necessary. Salesforce treats an insert on sharing objects as a "insert or update" operation. Feel free to axe that whole logic, and just insert all the rows; if there are duplicates, Salesforce will fix it for you. Sharing entries are considered unique if they have the same "ParentId, UserOrGroupId, SharingReason" values filled in. If a different AccessLevel is specified than the current sharing entry, it will be replaced with the new access level.

 

 

I hope this information helps you out.

 

 

 

 

DownstairsBDownstairsB

Hi, I'm having a similar issue with using a Map<id,Product2>

 

The weird thing is that it works perfectly in sandbox but not in development... wtf apex?

 

I'm not going to post the entire trigger code here, as it's not necessary, I have narrowed the issue down to the Map .get() method:

 

24 System.Debug('Keyset: '+pMap.keyset());
25 System.Debug('Product: '+pMap.get('01t50000001LcjyAAC').name);
26 Product2 testp;
27 if (Trigger.isInsert){
28 for (Product_Lot__c pl: Trigger.new){
29           System.Debug('Product__c: '+pl.Product__c);
30           testp = pMap.get(pl.Product__c); <--- Always Returns Null
31           testp.Inventory_on_Hand__c += pl.Quantity__c;    <--- Causes a null pointer exception
32      }

 

 

Results of Execute Anonymous:

 

11:33:25.101|USER_DEBUG|[24]|DEBUG|Keyset: {01t50000001LcjyAAC}

11:33:25.101|METHOD_EXIT|[24]|System.debug(ANY)

11:33:25.101|METHOD_ENTRY|[25]|System.debug(ANY)

11:33:25.101|METHOD_ENTRY|[25]|MAP.values()

11:33:25.101|METHOD_EXIT|[25]|MAP.values()

11:33:25.102|USER_DEBUG|[25]|DEBUG|Product: 2-Mercaptoethanol

11:33:25.102|METHOD_EXIT|[25]|System.debug(ANY)

11:33:25.102|METHOD_ENTRY|[29]|System.debug(ANY)

11:33:25.102|USER_DEBUG|[29]|DEBUG|Product__c: 01t50000001LcjyAAC

11:33:25.102|METHOD_EXIT|[29]|System.debug(ANY)

11:33:25.102|METHOD_ENTRY|[30]|MAP.get(ANY)

11:33:25.102|METHOD_EXIT|[30]|MAP.get(ANY)

11:33:25.102|EXCEPTION_THROWN|[31]|System.NullPointerException: Attempt to de-reference a null object

11:33:25.102|FATAL_ERROR|System.NullPointerException: Attempt to de-reference a null object

Trigger.Product_Lot_Trigger: line 31, column 4

 

So if you look at the highlighted lines (DEBUG outputs), you can plainly see that the map contains a valid ID, and the

hard-coded get() on line 25 returns the correct object and displays the correct name, so the Value is correct too.

Also you can see that the field Product__c (on line 29) exactly matches the key that is in the Map.

But line 30 is still returning NULL!!!!

 

I'm just starting to get angry at this point, because this works 100% correctly in the Sandbox.  Can anyone help?

sfdcfoxsfdcfox

It is more likely that Quantity__c or Inventory_On_Hand__c is null. Unlike formula fields, Apex Code treats nulls and zeroes differently from each other. You can't do 1 + null, for example, nor can you do Decimal di = null; Decimal x = 1 + di. Add a System.debug at the current line 31, and make sure that Inventory_On_Hand__c is not null, and Quantity__c is not null.

DownstairsBDownstairsB

Hi sfdcfox,

 

Indeed it was the Inventory_On_Hand__c field!

 

I actually decided to open a new thread for the issue, which has been resolved, thanks!
http://boards.developerforce.com/t5/Apex-Code-Development/Map-get-method-always-returns-NULL-on-developer-edition/td-p/286563