-1

Please help me find what I am doing wrong to update a user field. I am trying to update all existing users in my Drupal 8 instance. I could do the same thing easily in D7, but can't get it working in D8. When I execute the following code, I get an integrity violation on the SQL server:

If I take it out of the foreach loop and just execute it on one user it works fine, but with multiple users it works on the first one and then dies on the second user.

    $users = User::loadMultiple(\Drupal::entityQuery('user')->execute());
    foreach($users as $user){
      foreach(__get_user_units($user->getUsername()) as $unit){
        $drupalUnits[]=['value'=>$unit];
      }
      //Resulting Array Example (print_r output):
      //    Array
      //    (
      //        [0] => Array
      //            (
      //                [value] => Web Services
      //            )
      //        [1] => Array
      //            (
      //                [value] => Developers
      //            )
      //    )

      $user->get('field_unit')->setValue($drupalUnits);
      $user->save();
    }

The results from __get_user_units is an array of values to enter into the 'field_unit' multivalued field. the foreach then formats that information to match what by default comes from getting the value of that field.

The error that I receive says (Sanitized and formatted for readability):

Drupal\Core\Database\IntegrityConstraintViolationException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '-en' for key 'user__name':
INSERT INTO users_field_data
            (uid,
             langcode,
             preferred_langcode,
             preferred_admin_langcode,
             NAME,
             pass,
             mail,
             timezone,
             status,
             created,
             changed,
             access,
             login,
             init,
             default_langcode,
             ldap_user_puid_sid,
             ldap_user_puid,
             ldap_user_puid_property,
             ldap_user_current_dn,
             ldap_user_last_checked,
             ldap_user_ldap_exclude)
VALUES      (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2,
             :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5,
             :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8,
             :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11,
             :db_insert_placeholder_12, :db_insert_placeholder_13, :db_insert_placeholder_14,
             :db_insert_placeholder_15, :db_insert_placeholder_16, :db_insert_placeholder_17,
             :db_insert_placeholder_18, :db_insert_placeholder_19, :db_insert_placeholder_20); 
Array ( 
[:db_insert_placeholder_0] => 70
 [:db_insert_placeholder_1] => en 
 [:db_insert_placeholder_2] => en 
 [:db_insert_placeholder_3] => 
 [:db_insert_placeholder_4] => > 
 [:db_insert_placeholder_5] => >
 [:db_insert_placeholder_6] => > 
 [:db_insert_placeholder_7] => America/Detroit 
 [:db_insert_placeholder_8] => 1 
 [:db_insert_placeholder_9] => 1590514193 
 [:db_insert_placeholder_10] => 1610341561 
 [:db_insert_placeholder_11] => 1607618808 
 [:db_insert_placeholder_12] => 1590514193 
 [:db_insert_placeholder_13] =>  
 [:db_insert_placeholder_14] => 1 
 [:db_insert_placeholder_15] => 
 [:db_insert_placeholder_16] => 
 [:db_insert_placeholder_17] => 
 [:db_insert_placeholder_18] => > 
 [:db_insert_placeholder_19] => 1612193014 
 [:db_insert_placeholder_20] => 
 ) in Drupal\Core\Database\Connection->handleQueryException() (line 698 of /var/www/intranet8/web/core/lib/Drupal/Core/Database/Connection.php).

Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '<>-en' for key 'user__name': INSERT INTO users_field_data (uid, langcode, preferred_langcode, preferred_admin_langcode, NAME, pass, mail, timezone, status, created, changed, access, login, init, default_langcode, ldap_user_puid_sid, ldap_user_puid, ldap_user_puid_property, ldap_user_current_dn, ldap_user_last_checked, ldap_user_ldap_exclude) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11, :db_insert_placeholder_12, :db_insert_placeholder_13, :db_insert_placeholder_14, :db_insert_placeholder_15, :db_insert_placeholder_16, :db_insert_placeholder_17, :db_insert_placeholder_18, :db_insert_placeholder_19, :db_insert_placeholder_20); Array ( [:db_insert_placeholder_0] => 70 [:db_insert_placeholder_1] => en [:db_insert_placeholder_2] => en [:db_insert_placeholder_3] => [:db_insert_placeholder_4] => <> [:db_insert_placeholder_5] => <<PASSWORD_HASH>> [:db_insert_placeholder_6] => <<email_address>> [:db_insert_placeholder_7] => America/Detroit [:db_insert_placeholder_8] => 1 [:db_insert_placeholder_9] => 1590514193 [:db_insert_placeholder_10] => 1610341561 [:db_insert_placeholder_11] => 1607618808 [:db_insert_placeholder_12] => 1590514193 [:db_insert_placeholder_13] => <<init_address> [:db_insert_placeholder_14] => 1 [:db_insert_placeholder_15] => [:db_insert_placeholder_16] => [:db_insert_placeholder_17] => [:db_insert_placeholder_18] => <<LDAP_USER_DN>> [:db_insert_placeholder_19] => 1612193014 [:db_insert_placeholder_20] => ) in

Edit 1:

In looking closer, the user information seems to be combining user1 and user2 before saving. the init and password fields both have the value for user 2. I don't see how this could be unless 1) the save was somehow asynchronous or 2) the iterator for $users is not working properly.

Edit 2:

I have traced this down to the ldap_user module function ldap_user_user_presave() (which implements hook_user_presave). If I skip that function call everything works. Looking like it might not be connected to my code.

3
  • Whoever downvoted my post (and Abdulaziz's answer), it would be nice if you gave a reason why you downvoted it. – Kevin Finkenbinder Feb 2 at 13:32
  • The exception raised (Duplicate entry '-en' for key 'user__name') doesn't match with the value used for name shown in the question. Probably, when sanitizing the output, you sanitized too much, and this makes difficult to understand what happens. – kiamlaluno Feb 2 at 19:38
  • No, I didn't over sanitize, they don't match in the actual error. – Kevin Finkenbinder Feb 2 at 19:44
0

try this it is working with me:

$users = \Drupal::entityQuery('user')
      ->condition('status', '1')
      ->execute();
    foreach ($users as $uid) {

      $user = \Drupal::entityTypeManager()->getStorage('user')->load($uid);
      $user->set('field_unit', $drupalUnits);
      $user->save();

    }
1
  • Thank you for the suggestion, but that is encountering the exact same integrity violation and the same weird combining of users. – Kevin Finkenbinder Feb 1 at 22:39
0

The problem came down to an error in the way the ldap_user submodule of the ldap module was working. I had to refactor my code to only update one user per cron run (acceptible in my application) so that the LDAP code did not mess it up. The offending code has been reported to the maintainers of the LDAP module (https://www.drupal.org/project/ldap/issues/3196170) for their review. Without that error, either my original code or the code suggested by @abdulazizsaeed would have worked.

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.