Keep setSingleAttribute from deleting all other attributes of the user being updated.

This commit is contained in:
didiez 2016-09-22 10:42:24 +02:00
parent 33963f8aa7
commit 98bf095471
3 changed files with 31 additions and 5 deletions

View file

@ -140,9 +140,10 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
if (firstExistingAttrId != null) { if (firstExistingAttrId != null) {
// Remove attributes through HQL to avoid StaleUpdateException // Remove attributes through HQL to avoid StaleUpdateException
Query query = em.createNamedQuery("deleteUserAttributesOtherThan"); Query query = em.createNamedQuery("deleteUserAttributesByNameAndUserOtherThan");
query.setParameter("attrId", firstExistingAttrId); query.setParameter("name", name);
query.setParameter("userId", user.getId()); query.setParameter("userId", user.getId());
query.setParameter("attrId", firstExistingAttrId);
int numUpdated = query.executeUpdate(); int numUpdated = query.executeUpdate();
// Remove attribute from local entity // Remove attribute from local entity

View file

@ -43,7 +43,7 @@ import java.util.Set;
@NamedQuery(name="getAttributesByNameAndValue", query="select attr from UserAttributeEntity attr where attr.name = :name and attr.value = :value"), @NamedQuery(name="getAttributesByNameAndValue", query="select attr from UserAttributeEntity attr where attr.name = :name and attr.value = :value"),
@NamedQuery(name="deleteUserAttributesByRealm", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId)"), @NamedQuery(name="deleteUserAttributesByRealm", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId)"),
@NamedQuery(name="deleteUserAttributesByNameAndUser", query="delete from UserAttributeEntity attr where attr.user.id = :userId and attr.name = :name"), @NamedQuery(name="deleteUserAttributesByNameAndUser", query="delete from UserAttributeEntity attr where attr.user.id = :userId and attr.name = :name"),
@NamedQuery(name="deleteUserAttributesOtherThan", query="delete from UserAttributeEntity attr where attr.user.id = :userId and attr.id <> :attrId"), @NamedQuery(name="deleteUserAttributesByNameAndUserOtherThan", query="delete from UserAttributeEntity attr where attr.user.id = :userId and attr.name = :name and attr.id <> :attrId"),
@NamedQuery(name="deleteUserAttributesByRealmAndLink", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link)") @NamedQuery(name="deleteUserAttributesByRealmAndLink", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link)")
}) })
@Table(name="USER_ATTRIBUTE") @Table(name="USER_ATTRIBUTE")

View file

@ -17,6 +17,7 @@
package org.keycloak.testsuite.model; package org.keycloak.testsuite.model;
import com.google.common.collect.ImmutableMap;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
@ -236,6 +237,30 @@ public class UserModelTest extends AbstractModelTest {
commit(); commit();
} }
// KEYCLOAK-3608
@Test
public void testUpdateUserSingleAttribute() {
Map<String, List<String>> expected = ImmutableMap.of(
"key1", Arrays.asList("value3"),
"key2", Arrays.asList("value2"));
RealmModel realm = realmManager.createRealm("original");
UserModel user = session.users().addUser(realm, "user");
user.setSingleAttribute("key1", "value1");
user.setSingleAttribute("key2", "value2");
// Overwrite the first attribute
user.setSingleAttribute("key1", "value3");
Assert.assertEquals(expected, user.getAttributes());
commit();
realm = session.realms().getRealmByName("original");
Assert.assertEquals(expected, session.users().getUserByUsername("user", realm).getAttributes());
}
@Test @Test
public void testSearchByString() { public void testSearchByString() {
RealmModel realm = realmManager.createRealm("original"); RealmModel realm = realmManager.createRealm("original");