1

I'm having an issue with Null Pointer exceptions do to the fact that I'm using User ids, to match them with Case CreatedByID's. What I do is I take a set of Case ID's and then search for them inside my User Object. With some help from you guys I believe I worked out the comparisons and I don't get an error when I run tests through my IDE, but I do get an error if I attempt to create and save a Case I get a null pointer exception error. I'm really quite stuck, and i'm not sure how to manipulate CreatedById's. Can anyone else think of a reason why I'm getting a null pointer exception?

Plain English --

On Case there is 3 fields, FAE,ISM,and RSM, and these fields also sit on the User object. I need to go to the User objectand pull out those FAE,ISM,and RSM fields and auto populate them on the Case object in their respective places.

The error is coming across here

if (userList.get(c.Id).FAE1__c != null || String.isNotEmpty(userList.get(c.Id).FAE1__c) ) 

My Test Class

@isTest(seeAlldata=true) 
private class updateRSMISRFAESync {

 static testMethod void updateRSMISRFAESync1(){     
  String dateString = String.valueof(Datetime.now()).replace(' ','').replace(':','').replace('-','');
  String orgId = UserInfo.getOrganizationId();  
  Integer randomInt = Integer.valueOf(math.rint(math.random()*1000000));
  String uniqueName = orgId + dateString + randomInt;

  Profile p = [SELECT Id FROM Profile WHERE Name='Standard User']; 
  User u = new User(Alias = 'standt', 
  Email='standarduser@testorg.com', 
  EmailEncodingKey='UTF-8', 
  LastName='Testing', 
  LanguageLocaleKey='en_US', 
  LocaleSidKey='en_US', 
  ProfileId = p.Id, 
  TimeZoneSidKey='America/Los_Angeles', 
   Username = uniqueName + '@test' + orgId + '.org'); 

   Product2 p2 = new Product2();
  p2.Name='TestProduct';
  p2.IsActive=True; 
  p2.AE_Text__c='TestText';
  p2.Item_number__c='TestNumber';
  insert p2; 

   Case c = new Case(); 
    c.Product_old__c=p2.id; 
    c.Status='New';
    c.Origin='Email';
    c.Case_Level__c='Level 1 - Product Concept/Selection';
    c.Territory__c='Asia';
    c.Region__c='CHINA'; 
    system.debug('Creating a New case!   ' +c+ 'Created by!   ' +c.CreatedById);

  System.runAs(u) { 
System.debug('Current User: ' + UserInfo.getUserName()); 
System.debug('Current Profile: ' + UserInfo.getProfileId()); 
insert c; 

} 
Case newCase = [SELECT Id, CaseNumber, CreatedById FROM Case WHERE Id = :c.Id]; 
    System.debug(newCase); 
    System.assertEquals(u.Id, newCase.CreatedById); 
}
}

My Trigger

    if (Trigger.isExecuting) { // changed to check if we are in a trigger. 

    //if(trigger.new == null){ // exit if we have no Trigger.new (such as delete trigger)
    //   break;
    // }
    if (Trigger.isBefore || Trigger.isUpdate) {
        Set < Id > caseIdSet = new Set < Id > ();
        //Getting a set of case IDs, 
        for (Case c: [SELECT Id, CreatedById FROM Case WHERE isClosed != true]) {
            caseIdSet.add(c.CreatedById);
            //    system.debug('This is caseIdSet  ' + caseIdSet + '\n');              
        }

        Map < Id, User > userList = new Map < Id, User > ([SELECT id, FAE1__c, ISR__c, RSM__c FROM User WHERE Id IN: caseIdSet and Isactive = true]);


        for (Case c: trigger.new) //NOTE: This will fail if it is a "delete" trigger and is likely the source of your problems
        {
            system.debug('Inside For Loop! ');
            system.debug('THIS IS THE USER LIST   ' + userList);
            if (userList.isEmpty()) {
                system.debug('UserList is Empty! ');
                break;
            }
            if (userList.containsKey(c.CreatedById)) {
                system.debug('Inside ContainsKey! ');
                if (userList.get(c.Id).FAE1__c != null || String.isNotEmpty(userList.get(c.Id).FAE1__c)) {
                    system.debug('Inside FAE1 Condition ');
                    c.FAE__c = userList.get(c.Id).FAE1__c;
                } else if (userList.get(c.Id).ISR__c != null || String.isNotEmpty(userList.get(c.Id).ISR__c)) {
                    system.debug('Inside ISR Condition ');
                    c.ISR__c = userList.get(c.Id).ISR__c;
                } else if (userList.get(c.Id).RSM__c != null || String.isNotEmpty(userList.get(c.Id).RSM__c)) {
                    system.debug('Inside RSM Condition ');
                    c.RSM__c = userList.get(c.Id).RSM__c;
                }
            }
        }
    }
}
4

UPDATED

So you're saying you need a trigger that pulls some lookup fields from Case creator's record and puts them on the Case. Only on initial save (they can overwrite them as needed... meaning this can't be done with formula fields).

I'd do it more or less like that:

trigger CaseLookupPrepopulation on Case(before insert){
/*  "before insert" will fire only once, fix the fields if possible and that's it.

    At that time the case is not yet saved to the database
    so we don't know what Id or CaseNumber will be generated,
    the CreatedById field is still blank...

    But we know it's "you" who has caused the trigger to fire so we can look up your values.
    This trigger is executing for you = it's guaranteed you are creating all these cases ;)
    Bit philosophical ;)
*/

    User currentUser = [SELECT FAE1__c, ISR__c, RSM__c 
        FROM User
        WHERE Id = :UserInfo.getUserId()];

    for(Case c : trigger.new){
        // we will populate it with the value only
        // if user didn't consciously select anything else
        if(c.FAE__c == null) {
            c.FAE__c = currentUser.FAE1__c;
        }
        if(c.ISR__c == null) {
            c.ISR__c = currentUser.ISR__c;
        }
        if(c.RSM__c == null) {
            c.RSM__c = currentUser.RSM__c;
        }
    }
}

ORIGINAL

String.isNotEmpty(userList.get(c.Id).FAE1__c)

You have a list (well... map) of users. But you're trying to fetch something by Case Id.

Map<String, Integer> checkMeOut = new Map<String, Integer>{
    'one' => 1,
    'two' => 2,
    'three' => 3
};

System.debug(checkMeOut.get('one'));
System.debug(checkMeOut.get('asdfghjkl'));          // null
System.debug(checkMeOut.get('asdfghjkl').format()); // null pointer exception

You have LOTS of problems and misconceptions there like:

  • if (Trigger.isExecuting) (will be always true in a trigger's body, duh).
  • [SELECT Id, CreatedById FROM Case WHERE isClosed != true] grabs all cases in the system and not only the ones that are being modified now.
  • it's a "before update" trigger but your unit test only inserts the case, doesn't make subsequent updates... But if you'll change it to "before insert" - the createdbyid field will not be set yet, it'll become visible in "after insert".

Can you edit your question and just tell us in plain English what business requirement is this supposed to achieve?

1

You userList map uses User's IDs as keys, hence you should change the line that is causing error (and few others below it) to:

if (userList.get(c.CreatedById).FAE1__c != null || String.isNotEmpty(userList.get(c.CreatedById).FAE1__c) )

P.S. Having had another look at your 'Plain English' requirements - why don't you use workflows for this? Just create Workflow Rule on Case, set it to be evaluated after create (and possibly every time record is modified - depends on your needs, not very clear from your description). Finally add a x3 Field Update Actions for each of the fields you need to cary over from User and user formula builder to easily access those fields on User.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.