Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have added a custom field of type String to the User standard object. I'm trying to update it from a controller but even though I see the update succeeds in the Debug Log the value is not actually changing in the DB.

Any suggestions what is wrong?

This is the method (it is called from a getter method of one the class's members:

public static void updateLastVisited(Date dt){
    User usr;
    try{
        usr = new User(Id=UserInfo.getUserId(), Portfolio_Catalog_Last_Visit__c=dt.format());

        update usr;
    }
    catch(DMLException e){
        system.debug(LoggingLevel.WARN, e);    
    }
}

This is the debug log snippet:

22:50:26.407 (407350000)|METHOD_ENTRY|[65]|01pd00000022nbS|PortfolioCatalogController.updateLastVisited(Date) 22:50:26.407 (407365000)|VARIABLE_SCOPE_BEGIN|[757]|dt|Date|false|false 22:50:26.407 (407405000)|VARIABLE_ASSIGNMENT|[757]|dt|"2013-01-08T00:00:00.000Z" 22:50:26.407 (407417000)|HEAP_ALLOCATE|[758]|Bytes:5 22:50:26.407 (407426000)|STATEMENT_EXECUTE|[757] 22:50:26.407 (407430000)|STATEMENT_EXECUTE|[758] 22:50:26.407 (407439000)|VARIABLE_SCOPE_BEGIN|[758]|usr|User|true|false 22:50:26.407 (407448000)|VARIABLE_ASSIGNMENT|[758]|usr|null| 22:50:26.407 (407453000)|STATEMENT_EXECUTE|[759] 22:50:26.407 (407457000)|STATEMENT_EXECUTE|[759] 22:50:26.407 (407460000)|STATEMENT_EXECUTE|[760] 22:50:26.407 (407473000)|HEAP_ALLOCATE|[760]|Bytes:4 22:50:26.407 (407583000)|SYSTEM_METHOD_ENTRY|[760]|system.UserInfo.getUserId() 22:50:26.407 (407625000)|SYSTEM_METHOD_EXIT|[760]|system.UserInfo.getUserId() 22:50:26.407 (407689000)|VARIABLE_ASSIGNMENT|[760]|this.Id|"005d0000001KWYeAAO"|0xcd1e78c 22:50:26.407 (407719000)|SYSTEM_METHOD_ENTRY|[760]|Date.format() 22:50:26.407 (407773000)|HEAP_ALLOCATE|[760]|Bytes:8 22:50:26.407 (407785000)|SYSTEM_METHOD_EXIT|[760]|Date.format() 22:50:26.407 (407818000)|VARIABLE_ASSIGNMENT|[760]|this.Portfolio_Catalog_Last_Visit__c|"1/8/2013"|0xcd1e78c 22:50:26.407 (407866000)|VARIABLE_ASSIGNMENT|[760]|usr|{"Id":"005d0000001KWYeAAO","Portfolio_Catalog_La (11 more) ...":"1/8/2013"}|0xcd1e78c 22:50:26.407 (407875000)|STATEMENT_EXECUTE|[762] 22:50:26.407 (407901000)|HEAP_ALLOCATE|[762]|Bytes:8 22:50:26.407 (407911000)|DML_BEGIN|[762]|Op:Update|Type:User|Rows:1 22:50:26.407 (407927000)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8 22:50:26.470 (470058000)|DML_END|[762] 22:50:26.470 (470093000)|METHOD_EXIT|[65]|01pd00000022nbS|PortfolioCatalogController.updateLastVisited(Date) 22:50:26.470 (470103000)|STATEMENT_EXECUTE|[71] 22:50:26.470 (470127000)|CODE_UNIT_FINISHED|lastVisited

share|improve this question
2  
Can you post the debug log?. –  PepeFloyd Jan 8 '13 at 21:18
2  
Can you post the code where you do the update in your controller!!! –  rao Jan 8 '13 at 22:29
1  
Is there a custom Visualforce page as well? There might be some kind of error preventing the save. Add an apex:pageMessages component to the page and it will report the errors. It would definitely help if some of the code was posted. –  Peter Knolle Jan 8 '13 at 22:51
    
These is no error message on the page –  Dedo Jan 9 '13 at 6:53
add comment

2 Answers

up vote 0 down vote accepted

I think the reason might be because you are performing DML from a Getter (you mention your calling the updateLastVisited method from a Getter).

See this blog entry here for some details about situations where 'DML currently not allowed':

http://th3silverlining.com/2009/11/23/dml-currently-not-allowed/

I think to fix that, you would need to explicitly call the updateLastVisited method rather than having it a side effect of calling the Getter.

share|improve this answer
add comment

You could be running into a mixed DML issue if you are also making changes on other sObjects in the controller.

Try passing the User update off to a future method like this.

edit: referenced code courtesy of Abhinav Gupta

Perform DML on Non-Setup object type
Perform DML on Setup object type in @future methods.
Vice versa will also work. Here is the fixed code, we create new Apex class for the trigger code

ACCOUNT.TRIGGER

trigger Account on Account (after insert) {      
  List<group> newGroups = new List<group>();
  for (Account acc : Trigger.new) {
     newGroups.add(new Group(name=acc.Name, type='Regular', DoesIncludeBosses=false));
  }
  insert newGroups;

  Set<id> groupIds = new Map<id  , Group> (newGroups).keySet();
  // call in future context to avoid MIXED DML conflicts
  AccountHandler.createGroupMembers(groupIds); 
}


ACCOUNTHANDLER.CLS

This is the class with the future method to do setup and non-setup DML in different context

public class AccountHandler {
  @future
  public static void createGroupMembers(Set<Id> groupIds) {
    List<GroupMember> newGroupMembers = new List<GroupMember>();

    for (Id grpId : groupIds) {
        newGroupMembers.add(new GroupMember(GroupId=grpId, UserOrGroupId=UserInfo.getUserId()));
    }
      insert newGroupMembers;
  }
}
share|improve this answer
    
When I changed it to a future method the method is never called. I don't understand why? –  Dedo Jan 9 '13 at 6:52
    
@future methods are called asynchronously, are you sure it isn't getting called? It probably is, but you are not seeing the results in the debug log. –  Phil Hawthorn Jan 9 '13 at 8:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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