Is MIXED_DML_OPERATION in unit tests broken?












6















We have a nightly integration that runs all tests and reports any errors against production, currently on Winter '19. Everything was fine until January 14th, 2019, when 13 previously passing tests started to fail with MIXED_DML_OPERATION exceptions. The exact same tests are passing in my Spring '19 sandbox. I created a new demonstration class in my Developer Org, which is also Winter '19, and the tests are passing there, too. Is there a documented change on MIXED_DML_OPERATION, or is a bug being fixed?





@isTest class MixedDMLError {
@isTest static void test() {
User u = [select Email, TimezoneSidKey, LocaleSidkey, LastName, EmailEncodingKey, ProfileId, LanguageLocaleKey from user where id = :UserInfo.getUserId()];
u = u.clone(false);
u.username = 'user'+math.random()+'@org.random';
u.alias = (math.random()+'').remove('.').left(8);
insert u;
Account a = new Account(Name=Math.random()+'');
insert a;
}
}




Edit



It has been mentioned that UserRoleId might be the culprit, so I checked the source code. Here's the actual method creating the user:



public static User createUser( String profileName,String usrName, Boolean doInsert){
Profile pro =[SELECT Id From Profile WHERE Name = :profileName];
User usr = new user(
FirstName='USR_FN',
LastName='USR_LN',
Username=usrName,
ProfileId=pro.Id,
email='example@example.com',
emailencodingkey='UTF-8',
languagelocalekey='en_US',
localesidkey='en_US',
timezonesidkey='America/Los_Angeles',
alias='USR_FN'.substring(0,1)+'USR_LN'.substring(0,1)+string.valueof( Math.random()).substring(0,3)
);

if(doInsert)
insert usr;

return usr;
}


The role is left null, so unfortunately, that does not explain the difference. Both the unit test and the utility class it calls are identical in the Sandboxes I've tested and Production.





Edit 2



This problem only occurs when running tests. During deployments/validations using Run All Tests or Run Specified Tests, the operation succeeds without any errors. This appears to be a bug in how tests are run.










share|improve this question





























    6















    We have a nightly integration that runs all tests and reports any errors against production, currently on Winter '19. Everything was fine until January 14th, 2019, when 13 previously passing tests started to fail with MIXED_DML_OPERATION exceptions. The exact same tests are passing in my Spring '19 sandbox. I created a new demonstration class in my Developer Org, which is also Winter '19, and the tests are passing there, too. Is there a documented change on MIXED_DML_OPERATION, or is a bug being fixed?





    @isTest class MixedDMLError {
    @isTest static void test() {
    User u = [select Email, TimezoneSidKey, LocaleSidkey, LastName, EmailEncodingKey, ProfileId, LanguageLocaleKey from user where id = :UserInfo.getUserId()];
    u = u.clone(false);
    u.username = 'user'+math.random()+'@org.random';
    u.alias = (math.random()+'').remove('.').left(8);
    insert u;
    Account a = new Account(Name=Math.random()+'');
    insert a;
    }
    }




    Edit



    It has been mentioned that UserRoleId might be the culprit, so I checked the source code. Here's the actual method creating the user:



    public static User createUser( String profileName,String usrName, Boolean doInsert){
    Profile pro =[SELECT Id From Profile WHERE Name = :profileName];
    User usr = new user(
    FirstName='USR_FN',
    LastName='USR_LN',
    Username=usrName,
    ProfileId=pro.Id,
    email='example@example.com',
    emailencodingkey='UTF-8',
    languagelocalekey='en_US',
    localesidkey='en_US',
    timezonesidkey='America/Los_Angeles',
    alias='USR_FN'.substring(0,1)+'USR_LN'.substring(0,1)+string.valueof( Math.random()).substring(0,3)
    );

    if(doInsert)
    insert usr;

    return usr;
    }


    The role is left null, so unfortunately, that does not explain the difference. Both the unit test and the utility class it calls are identical in the Sandboxes I've tested and Production.





    Edit 2



    This problem only occurs when running tests. During deployments/validations using Run All Tests or Run Specified Tests, the operation succeeds without any errors. This appears to be a bug in how tests are run.










    share|improve this question



























      6












      6








      6








      We have a nightly integration that runs all tests and reports any errors against production, currently on Winter '19. Everything was fine until January 14th, 2019, when 13 previously passing tests started to fail with MIXED_DML_OPERATION exceptions. The exact same tests are passing in my Spring '19 sandbox. I created a new demonstration class in my Developer Org, which is also Winter '19, and the tests are passing there, too. Is there a documented change on MIXED_DML_OPERATION, or is a bug being fixed?





      @isTest class MixedDMLError {
      @isTest static void test() {
      User u = [select Email, TimezoneSidKey, LocaleSidkey, LastName, EmailEncodingKey, ProfileId, LanguageLocaleKey from user where id = :UserInfo.getUserId()];
      u = u.clone(false);
      u.username = 'user'+math.random()+'@org.random';
      u.alias = (math.random()+'').remove('.').left(8);
      insert u;
      Account a = new Account(Name=Math.random()+'');
      insert a;
      }
      }




      Edit



      It has been mentioned that UserRoleId might be the culprit, so I checked the source code. Here's the actual method creating the user:



      public static User createUser( String profileName,String usrName, Boolean doInsert){
      Profile pro =[SELECT Id From Profile WHERE Name = :profileName];
      User usr = new user(
      FirstName='USR_FN',
      LastName='USR_LN',
      Username=usrName,
      ProfileId=pro.Id,
      email='example@example.com',
      emailencodingkey='UTF-8',
      languagelocalekey='en_US',
      localesidkey='en_US',
      timezonesidkey='America/Los_Angeles',
      alias='USR_FN'.substring(0,1)+'USR_LN'.substring(0,1)+string.valueof( Math.random()).substring(0,3)
      );

      if(doInsert)
      insert usr;

      return usr;
      }


      The role is left null, so unfortunately, that does not explain the difference. Both the unit test and the utility class it calls are identical in the Sandboxes I've tested and Production.





      Edit 2



      This problem only occurs when running tests. During deployments/validations using Run All Tests or Run Specified Tests, the operation succeeds without any errors. This appears to be a bug in how tests are run.










      share|improve this question
















      We have a nightly integration that runs all tests and reports any errors against production, currently on Winter '19. Everything was fine until January 14th, 2019, when 13 previously passing tests started to fail with MIXED_DML_OPERATION exceptions. The exact same tests are passing in my Spring '19 sandbox. I created a new demonstration class in my Developer Org, which is also Winter '19, and the tests are passing there, too. Is there a documented change on MIXED_DML_OPERATION, or is a bug being fixed?





      @isTest class MixedDMLError {
      @isTest static void test() {
      User u = [select Email, TimezoneSidKey, LocaleSidkey, LastName, EmailEncodingKey, ProfileId, LanguageLocaleKey from user where id = :UserInfo.getUserId()];
      u = u.clone(false);
      u.username = 'user'+math.random()+'@org.random';
      u.alias = (math.random()+'').remove('.').left(8);
      insert u;
      Account a = new Account(Name=Math.random()+'');
      insert a;
      }
      }




      Edit



      It has been mentioned that UserRoleId might be the culprit, so I checked the source code. Here's the actual method creating the user:



      public static User createUser( String profileName,String usrName, Boolean doInsert){
      Profile pro =[SELECT Id From Profile WHERE Name = :profileName];
      User usr = new user(
      FirstName='USR_FN',
      LastName='USR_LN',
      Username=usrName,
      ProfileId=pro.Id,
      email='example@example.com',
      emailencodingkey='UTF-8',
      languagelocalekey='en_US',
      localesidkey='en_US',
      timezonesidkey='America/Los_Angeles',
      alias='USR_FN'.substring(0,1)+'USR_LN'.substring(0,1)+string.valueof( Math.random()).substring(0,3)
      );

      if(doInsert)
      insert usr;

      return usr;
      }


      The role is left null, so unfortunately, that does not explain the difference. Both the unit test and the utility class it calls are identical in the Sandboxes I've tested and Production.





      Edit 2



      This problem only occurs when running tests. During deployments/validations using Run All Tests or Run Specified Tests, the operation succeeds without any errors. This appears to be a bug in how tests are run.







      apex unit-test bug






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 1 hour ago







      sfdcfox

















      asked 3 hours ago









      sfdcfoxsfdcfox

      249k11192428




      249k11192428






















          2 Answers
          2






          active

          oldest

          votes


















          3














          Likely not a bug. Note from the documentation on sObjects That Cannot Be Used Together in DML Operations:




          You can insert a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if UserRoleId is specified as null.




          Your unit test does not filter on this field, nor clear it out before inserting the clone.



          If you are going to create a User record by cloning the running user, make sure to set UserRoleId = null before your insert call.



          If you do not do so, test runs will not behave the same for each user who runs them, or if certain attributes on that user change.






          share|improve this answer
























          • The real code does not use a query, actually; you'll want to see my edit.

            – sfdcfox
            2 hours ago











          • Yeah makes more sense now. Do you have any triggers or workflows which might be setting UserRoleId inadvertently? Hopefully not in a managed package...

            – Adrian Larson
            2 hours ago



















          -1














          You can not update account and user in same transaction. Are you sure that it was working previously or you added some field while retrieving user?



          This is the documentation reference https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm



          You can update a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if the following fields are not also updated:




          • UserRoleId

          • IsActive

          • ForecastEnabled

          • IsPortalEnabled

          • Username

          • ProfileId


          Please try removing profile id and see the results, moreover you need not to insert user to do a runAs you can pass the user if you need to test based on profile






          share|improve this answer



















          • 1





            Yes, I know about System.runAs, and I've advised our team that we need to clean up the code. But we have logs showing successful nightly runs until this morning at about 3am MST (America/Denver). Further, the test in the question is passing in a Winter '19 Developer Org and a Spring '19 Sandbox Org. We've been doing deployments twice a week without any problems until today. Our diffs show no changes at all to those classes in months, either, they just started failing.

            – sfdcfox
            2 hours ago













          • You need to remove the profile ID, request you to see the documentation. why you need the profile id in the soql if you are not using

            – Avijit Chakraborty
            2 hours ago













          • @AvijitChakraborty it works in Winter 19, so it's not a code issue and SF issue. The code provided by sfdcfox is pseudo code.

            – Pranay Jaiswal
            2 hours ago













          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "459"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f246596%2fis-mixed-dml-operation-in-unit-tests-broken%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          Likely not a bug. Note from the documentation on sObjects That Cannot Be Used Together in DML Operations:




          You can insert a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if UserRoleId is specified as null.




          Your unit test does not filter on this field, nor clear it out before inserting the clone.



          If you are going to create a User record by cloning the running user, make sure to set UserRoleId = null before your insert call.



          If you do not do so, test runs will not behave the same for each user who runs them, or if certain attributes on that user change.






          share|improve this answer
























          • The real code does not use a query, actually; you'll want to see my edit.

            – sfdcfox
            2 hours ago











          • Yeah makes more sense now. Do you have any triggers or workflows which might be setting UserRoleId inadvertently? Hopefully not in a managed package...

            – Adrian Larson
            2 hours ago
















          3














          Likely not a bug. Note from the documentation on sObjects That Cannot Be Used Together in DML Operations:




          You can insert a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if UserRoleId is specified as null.




          Your unit test does not filter on this field, nor clear it out before inserting the clone.



          If you are going to create a User record by cloning the running user, make sure to set UserRoleId = null before your insert call.



          If you do not do so, test runs will not behave the same for each user who runs them, or if certain attributes on that user change.






          share|improve this answer
























          • The real code does not use a query, actually; you'll want to see my edit.

            – sfdcfox
            2 hours ago











          • Yeah makes more sense now. Do you have any triggers or workflows which might be setting UserRoleId inadvertently? Hopefully not in a managed package...

            – Adrian Larson
            2 hours ago














          3












          3








          3







          Likely not a bug. Note from the documentation on sObjects That Cannot Be Used Together in DML Operations:




          You can insert a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if UserRoleId is specified as null.




          Your unit test does not filter on this field, nor clear it out before inserting the clone.



          If you are going to create a User record by cloning the running user, make sure to set UserRoleId = null before your insert call.



          If you do not do so, test runs will not behave the same for each user who runs them, or if certain attributes on that user change.






          share|improve this answer













          Likely not a bug. Note from the documentation on sObjects That Cannot Be Used Together in DML Operations:




          You can insert a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if UserRoleId is specified as null.




          Your unit test does not filter on this field, nor clear it out before inserting the clone.



          If you are going to create a User record by cloning the running user, make sure to set UserRoleId = null before your insert call.



          If you do not do so, test runs will not behave the same for each user who runs them, or if certain attributes on that user change.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 2 hours ago









          Adrian LarsonAdrian Larson

          106k19112238




          106k19112238













          • The real code does not use a query, actually; you'll want to see my edit.

            – sfdcfox
            2 hours ago











          • Yeah makes more sense now. Do you have any triggers or workflows which might be setting UserRoleId inadvertently? Hopefully not in a managed package...

            – Adrian Larson
            2 hours ago



















          • The real code does not use a query, actually; you'll want to see my edit.

            – sfdcfox
            2 hours ago











          • Yeah makes more sense now. Do you have any triggers or workflows which might be setting UserRoleId inadvertently? Hopefully not in a managed package...

            – Adrian Larson
            2 hours ago

















          The real code does not use a query, actually; you'll want to see my edit.

          – sfdcfox
          2 hours ago





          The real code does not use a query, actually; you'll want to see my edit.

          – sfdcfox
          2 hours ago













          Yeah makes more sense now. Do you have any triggers or workflows which might be setting UserRoleId inadvertently? Hopefully not in a managed package...

          – Adrian Larson
          2 hours ago





          Yeah makes more sense now. Do you have any triggers or workflows which might be setting UserRoleId inadvertently? Hopefully not in a managed package...

          – Adrian Larson
          2 hours ago













          -1














          You can not update account and user in same transaction. Are you sure that it was working previously or you added some field while retrieving user?



          This is the documentation reference https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm



          You can update a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if the following fields are not also updated:




          • UserRoleId

          • IsActive

          • ForecastEnabled

          • IsPortalEnabled

          • Username

          • ProfileId


          Please try removing profile id and see the results, moreover you need not to insert user to do a runAs you can pass the user if you need to test based on profile






          share|improve this answer



















          • 1





            Yes, I know about System.runAs, and I've advised our team that we need to clean up the code. But we have logs showing successful nightly runs until this morning at about 3am MST (America/Denver). Further, the test in the question is passing in a Winter '19 Developer Org and a Spring '19 Sandbox Org. We've been doing deployments twice a week without any problems until today. Our diffs show no changes at all to those classes in months, either, they just started failing.

            – sfdcfox
            2 hours ago













          • You need to remove the profile ID, request you to see the documentation. why you need the profile id in the soql if you are not using

            – Avijit Chakraborty
            2 hours ago













          • @AvijitChakraborty it works in Winter 19, so it's not a code issue and SF issue. The code provided by sfdcfox is pseudo code.

            – Pranay Jaiswal
            2 hours ago


















          -1














          You can not update account and user in same transaction. Are you sure that it was working previously or you added some field while retrieving user?



          This is the documentation reference https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm



          You can update a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if the following fields are not also updated:




          • UserRoleId

          • IsActive

          • ForecastEnabled

          • IsPortalEnabled

          • Username

          • ProfileId


          Please try removing profile id and see the results, moreover you need not to insert user to do a runAs you can pass the user if you need to test based on profile






          share|improve this answer



















          • 1





            Yes, I know about System.runAs, and I've advised our team that we need to clean up the code. But we have logs showing successful nightly runs until this morning at about 3am MST (America/Denver). Further, the test in the question is passing in a Winter '19 Developer Org and a Spring '19 Sandbox Org. We've been doing deployments twice a week without any problems until today. Our diffs show no changes at all to those classes in months, either, they just started failing.

            – sfdcfox
            2 hours ago













          • You need to remove the profile ID, request you to see the documentation. why you need the profile id in the soql if you are not using

            – Avijit Chakraborty
            2 hours ago













          • @AvijitChakraborty it works in Winter 19, so it's not a code issue and SF issue. The code provided by sfdcfox is pseudo code.

            – Pranay Jaiswal
            2 hours ago
















          -1












          -1








          -1







          You can not update account and user in same transaction. Are you sure that it was working previously or you added some field while retrieving user?



          This is the documentation reference https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm



          You can update a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if the following fields are not also updated:




          • UserRoleId

          • IsActive

          • ForecastEnabled

          • IsPortalEnabled

          • Username

          • ProfileId


          Please try removing profile id and see the results, moreover you need not to insert user to do a runAs you can pass the user if you need to test based on profile






          share|improve this answer













          You can not update account and user in same transaction. Are you sure that it was working previously or you added some field while retrieving user?



          This is the documentation reference https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects.htm



          You can update a user in a transaction with other sObjects in Apex code saved using Salesforce API version 15.0 and later if the following fields are not also updated:




          • UserRoleId

          • IsActive

          • ForecastEnabled

          • IsPortalEnabled

          • Username

          • ProfileId


          Please try removing profile id and see the results, moreover you need not to insert user to do a runAs you can pass the user if you need to test based on profile







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 2 hours ago









          Avijit ChakrabortyAvijit Chakraborty

          1,1101515




          1,1101515








          • 1





            Yes, I know about System.runAs, and I've advised our team that we need to clean up the code. But we have logs showing successful nightly runs until this morning at about 3am MST (America/Denver). Further, the test in the question is passing in a Winter '19 Developer Org and a Spring '19 Sandbox Org. We've been doing deployments twice a week without any problems until today. Our diffs show no changes at all to those classes in months, either, they just started failing.

            – sfdcfox
            2 hours ago













          • You need to remove the profile ID, request you to see the documentation. why you need the profile id in the soql if you are not using

            – Avijit Chakraborty
            2 hours ago













          • @AvijitChakraborty it works in Winter 19, so it's not a code issue and SF issue. The code provided by sfdcfox is pseudo code.

            – Pranay Jaiswal
            2 hours ago
















          • 1





            Yes, I know about System.runAs, and I've advised our team that we need to clean up the code. But we have logs showing successful nightly runs until this morning at about 3am MST (America/Denver). Further, the test in the question is passing in a Winter '19 Developer Org and a Spring '19 Sandbox Org. We've been doing deployments twice a week without any problems until today. Our diffs show no changes at all to those classes in months, either, they just started failing.

            – sfdcfox
            2 hours ago













          • You need to remove the profile ID, request you to see the documentation. why you need the profile id in the soql if you are not using

            – Avijit Chakraborty
            2 hours ago













          • @AvijitChakraborty it works in Winter 19, so it's not a code issue and SF issue. The code provided by sfdcfox is pseudo code.

            – Pranay Jaiswal
            2 hours ago










          1




          1





          Yes, I know about System.runAs, and I've advised our team that we need to clean up the code. But we have logs showing successful nightly runs until this morning at about 3am MST (America/Denver). Further, the test in the question is passing in a Winter '19 Developer Org and a Spring '19 Sandbox Org. We've been doing deployments twice a week without any problems until today. Our diffs show no changes at all to those classes in months, either, they just started failing.

          – sfdcfox
          2 hours ago







          Yes, I know about System.runAs, and I've advised our team that we need to clean up the code. But we have logs showing successful nightly runs until this morning at about 3am MST (America/Denver). Further, the test in the question is passing in a Winter '19 Developer Org and a Spring '19 Sandbox Org. We've been doing deployments twice a week without any problems until today. Our diffs show no changes at all to those classes in months, either, they just started failing.

          – sfdcfox
          2 hours ago















          You need to remove the profile ID, request you to see the documentation. why you need the profile id in the soql if you are not using

          – Avijit Chakraborty
          2 hours ago







          You need to remove the profile ID, request you to see the documentation. why you need the profile id in the soql if you are not using

          – Avijit Chakraborty
          2 hours ago















          @AvijitChakraborty it works in Winter 19, so it's not a code issue and SF issue. The code provided by sfdcfox is pseudo code.

          – Pranay Jaiswal
          2 hours ago







          @AvijitChakraborty it works in Winter 19, so it's not a code issue and SF issue. The code provided by sfdcfox is pseudo code.

          – Pranay Jaiswal
          2 hours ago




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Salesforce Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f246596%2fis-mixed-dml-operation-in-unit-tests-broken%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          List directoties down one level, excluding some named directories and files

          list processes belonging to a network namespace

          list systemd RuntimeDirectory mounts