diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java
index e205de6eb5..e4565c8f9d 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java
@@ -231,7 +231,7 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider {
}
- private String getTable(String table, String defaultSchema) {
+ public static String getTable(String table, String defaultSchema) {
return defaultSchema != null ? defaultSchema + "." + table : table;
}
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/AddRealmCodeSecret.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/AddRealmCodeSecret.java
index 48941d3981..3190485b1e 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/AddRealmCodeSecret.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/AddRealmCodeSecret.java
@@ -12,6 +12,7 @@ import liquibase.statement.SqlStatement;
import liquibase.statement.core.UpdateStatement;
import liquibase.structure.core.Schema;
import liquibase.structure.core.Table;
+import org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.sql.Connection;
@@ -36,7 +37,7 @@ public class AddRealmCodeSecret implements CustomSqlChange {
String correctedTableName = database.correctObjectName("REALM", Table.class);
if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(correctedTableName), database)) {
- ResultSet resultSet = connection.createStatement().executeQuery("SELECT ID FROM REALM WHERE CODE_SECRET IS NULL");
+ ResultSet resultSet = connection.createStatement().executeQuery("SELECT ID FROM " + LiquibaseJpaUpdaterProvider.getTable(correctedTableName, database.getDefaultSchemaName()) + " WHERE CODE_SECRET IS NULL");
while (resultSet.next()) {
String id = resultSet.getString(1);
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/CustomKeycloakTask.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/CustomKeycloakTask.java
index 1b63bdb281..6b0ea2cb4c 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/CustomKeycloakTask.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/CustomKeycloakTask.java
@@ -16,6 +16,7 @@ import liquibase.snapshot.SnapshotGeneratorFactory;
import liquibase.statement.SqlStatement;
import liquibase.structure.core.Table;
import org.jboss.logging.Logger;
+import org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider;
import org.keycloak.connections.jpa.updater.liquibase.ThreadLocalSessionContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.services.DefaultKeycloakSessionFactory;
@@ -88,7 +89,7 @@ public abstract class CustomKeycloakTask implements CustomSqlChange {
try {
String correctedTableName = database.correctObjectName("REALM", Table.class);
if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(correctedTableName), database)) {
- ResultSet resultSet = connection.createStatement().executeQuery("SELECT ID FROM REALM");
+ ResultSet resultSet = connection.createStatement().executeQuery("SELECT ID FROM " + getTableName(correctedTableName));
try {
return (resultSet.next());
} finally {
@@ -108,4 +109,9 @@ public abstract class CustomKeycloakTask implements CustomSqlChange {
protected abstract void generateStatementsImpl() throws CustomChangeException;
protected abstract String getTaskId();
+
+ // get Table name for sql selects
+ protected String getTableName(String tableName) {
+ return LiquibaseJpaUpdaterProvider.getTable(tableName, database.getDefaultSchemaName());
+ }
}
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
index 895a7856a7..70c62372f6 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
@@ -11,6 +11,7 @@ import liquibase.statement.core.InsertStatement;
import liquibase.statement.core.UpdateStatement;
import liquibase.structure.core.Table;
import org.keycloak.Config;
+import org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider;
import org.keycloak.migration.MigrationProvider;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClaimMask;
@@ -49,7 +50,10 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
String identityProviderTableName = database.correctObjectName("IDENTITY_PROVIDER", Table.class);
String idpConfigTableName = database.correctObjectName("IDENTITY_PROVIDER_CONFIG", Table.class);
- PreparedStatement statement = jdbcConnection.prepareStatement("select RSC.NAME, VALUE, REALM_ID, UPDATE_PROFILE_ON_SOC_LOGIN from REALM_SOCIAL_CONFIG RSC,REALM where RSC.REALM_ID = REALM.ID ORDER BY RSC.REALM_ID, RSC.NAME");
+ String realmSocialConfigTable = getTableName("REALM_SOCIAL_CONFIG");
+ String realmTableName = getTableName("REALM");
+ PreparedStatement statement = jdbcConnection.prepareStatement("select RSC.NAME, VALUE, REALM_ID, UPDATE_PROFILE_ON_SOC_LOGIN from " + realmSocialConfigTable + " RSC," + realmTableName +
+ " REALM where RSC.REALM_ID = REALM.ID ORDER BY RSC.REALM_ID, RSC.NAME");
try {
ResultSet resultSet = statement.executeQuery();
try {
@@ -124,7 +128,7 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
protected void convertSocialToIdFedUsers() throws SQLException, DatabaseException {
String federatedIdentityTableName = database.correctObjectName("FEDERATED_IDENTITY", Table.class);
- PreparedStatement statement = jdbcConnection.prepareStatement("select REALM_ID, USER_ID, SOCIAL_PROVIDER, SOCIAL_USER_ID, SOCIAL_USERNAME from USER_SOCIAL_LINK");
+ PreparedStatement statement = jdbcConnection.prepareStatement("select REALM_ID, USER_ID, SOCIAL_PROVIDER, SOCIAL_USER_ID, SOCIAL_USERNAME from " + getTableName("USER_SOCIAL_LINK"));
try {
ResultSet resultSet = statement.executeQuery();
try {
@@ -170,7 +174,7 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
String adminRoleId = getAdminRoleId();
String masterRealmId = Config.getAdminRealm();
- PreparedStatement statement = jdbcConnection.prepareStatement("select NAME from REALM");
+ PreparedStatement statement = jdbcConnection.prepareStatement("select NAME from " + getTableName("REALM"));
try {
ResultSet resultSet = statement.executeQuery();
try {
@@ -178,7 +182,7 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
String realmName = resultSet.getString("NAME");
String masterAdminAppName = realmName + "-realm";
- PreparedStatement statement2 = jdbcConnection.prepareStatement("select ID from CLIENT where REALM_ID = ? AND NAME = ?");
+ PreparedStatement statement2 = jdbcConnection.prepareStatement("select ID from " + getTableName("CLIENT") + " where REALM_ID = ? AND NAME = ?");
statement2.setString(1, masterRealmId);
statement2.setString(2, masterAdminAppName);
@@ -209,7 +213,7 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
}
private String getAdminRoleId() throws SQLException, DatabaseException {
- PreparedStatement statement = jdbcConnection.prepareStatement("select ID from KEYCLOAK_ROLE where NAME = ? AND REALM = ?");
+ PreparedStatement statement = jdbcConnection.prepareStatement("select ID from " + getTableName("KEYCLOAK_ROLE") + " where NAME = ? AND REALM = ?");
statement.setString(1, AdminRoles.ADMIN);
statement.setString(2, Config.getAdminRealm());
@@ -231,7 +235,8 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
protected void addNewRealmAdminRoles() throws SQLException, DatabaseException {
- PreparedStatement statement = jdbcConnection.prepareStatement("select CLIENT.ID REALM_ADMIN_APP_ID, CLIENT.REALM_ID REALM_ID, KEYCLOAK_ROLE.ID ADMIN_ROLE_ID from CLIENT,KEYCLOAK_ROLE where KEYCLOAK_ROLE.APPLICATION = CLIENT.ID AND CLIENT.NAME = 'realm-management' AND KEYCLOAK_ROLE.NAME = ?");
+ PreparedStatement statement = jdbcConnection.prepareStatement("select CLIENT.ID REALM_ADMIN_APP_ID, CLIENT.REALM_ID REALM_ID, KEYCLOAK_ROLE.ID ADMIN_ROLE_ID from " +
+ getTableName("CLIENT") + " CLIENT," + getTableName("KEYCLOAK_ROLE") + " KEYCLOAK_ROLE where KEYCLOAK_ROLE.APPLICATION = CLIENT.ID AND CLIENT.NAME = 'realm-management' AND KEYCLOAK_ROLE.NAME = ?");
statement.setString(1, AdminRoles.REALM_ADMIN);
try {
@@ -280,7 +285,7 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
String protocolMapperTableName = database.correctObjectName("PROTOCOL_MAPPER", Table.class);
String protocolMapperCfgTableName = database.correctObjectName("PROTOCOL_MAPPER_CONFIG", Table.class);
- PreparedStatement statement = jdbcConnection.prepareStatement("select ID, NAME, ALLOWED_CLAIMS_MASK from CLIENT");
+ PreparedStatement statement = jdbcConnection.prepareStatement("select ID, NAME, ALLOWED_CLAIMS_MASK from " + getTableName("CLIENT"));
try {
ResultSet resultSet = statement.executeQuery();
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java
index 00f9b0cd1e..07d6c7e14d 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_CR1.java
@@ -19,7 +19,7 @@ public class JpaUpdate1_2_0_CR1 extends CustomKeycloakTask {
try {
String trueValue = DataTypeFactory.getInstance().getTrueBooleanValue(database);
- PreparedStatement statement = jdbcConnection.prepareStatement("select CLIENT.REALM_ID, CLIENT.ID CLIENT_ID from CLIENT where CLIENT.CONSENT_REQUIRED = " + trueValue);
+ PreparedStatement statement = jdbcConnection.prepareStatement("select CLIENT.REALM_ID, CLIENT.ID CLIENT_ID from " + getTableName("CLIENT") + " CLIENT where CLIENT.CONSENT_REQUIRED = " + trueValue);
try {
ResultSet resultSet = statement.executeQuery();
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_4_0_Final.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_4_0_Final.java
index 1f60d6bdcd..579b108cdf 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_4_0_Final.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_4_0_Final.java
@@ -20,7 +20,7 @@ public class JpaUpdate1_4_0_Final extends CustomKeycloakTask {
String userAttributeTableName = database.correctObjectName("USER_ATTRIBUTE", Table.class);
try {
- PreparedStatement statement = jdbcConnection.prepareStatement("select NAME, USER_ID from USER_ATTRIBUTE");
+ PreparedStatement statement = jdbcConnection.prepareStatement("select NAME, USER_ID from " + getTableName("USER_ATTRIBUTE"));
try {
ResultSet resultSet = statement.executeQuery();
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.5.0.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.5.0.xml
index 9ad3c64d35..52930a3a78 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.5.0.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.5.0.xml
@@ -61,5 +61,10 @@
+
+
+
+
+
diff --git a/connections/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java b/connections/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java
index a79c82b228..e011e114f3 100755
--- a/connections/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java
+++ b/connections/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java
@@ -4,6 +4,7 @@ import org.hibernate.ejb.AvailableSettings;
import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
+import org.keycloak.connections.jpa.util.JpaUtils;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
@@ -108,7 +109,7 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
String schema = config.get("schema");
if (schema != null) {
- properties.put("hibernate.default_schema", schema);
+ properties.put(JpaUtils.HIBERNATE_DEFAULT_SCHEMA, schema);
}
if (databaseSchema != null) {
diff --git a/connections/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java b/connections/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java
new file mode 100644
index 0000000000..7e29d31ab2
--- /dev/null
+++ b/connections/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java
@@ -0,0 +1,16 @@
+package org.keycloak.connections.jpa.util;
+
+import javax.persistence.EntityManager;
+
+/**
+ * @author Marek Posolda
+ */
+public class JpaUtils {
+
+ public static final String HIBERNATE_DEFAULT_SCHEMA = "hibernate.default_schema";
+
+ public static String getTableNameForNativeQuery(String tableName, EntityManager em) {
+ String schema = (String) em.getEntityManagerFactory().getProperties().get(HIBERNATE_DEFAULT_SCHEMA);
+ return (schema==null) ? tableName : schema + "." + tableName;
+ }
+}
diff --git a/model/api/src/main/java/org/keycloak/models/UserFederationManager.java b/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
index fd4569ba20..13c05f8908 100755
--- a/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
+++ b/model/api/src/main/java/org/keycloak/models/UserFederationManager.java
@@ -314,8 +314,8 @@ public class UserFederationManager implements UserProvider {
}
@Override
- public List searchForUserByUserAttributes(Map attributes, RealmModel realm) {
- return session.userStorage().searchForUserByUserAttributes(attributes, realm);
+ public List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
+ return session.userStorage().searchForUserByUserAttribute(attrName, attrValue, realm);
}
@Override
diff --git a/model/api/src/main/java/org/keycloak/models/UserProvider.java b/model/api/src/main/java/org/keycloak/models/UserProvider.java
index 1690b7a70c..8712f2bfc4 100755
--- a/model/api/src/main/java/org/keycloak/models/UserProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserProvider.java
@@ -37,7 +37,7 @@ public interface UserProvider extends Provider {
List searchForUserByAttributes(Map attributes, RealmModel realm, int firstResult, int maxResults);
// Searching by UserModel.attribute (not property)
- List searchForUserByUserAttributes(Map attributes, RealmModel realm);
+ List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm);
Set getFederatedIdentities(UserModel user, RealmModel realm);
FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
diff --git a/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java b/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
index 0bcc37a8b2..40547a82db 100755
--- a/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
+++ b/model/file/src/main/java/org/keycloak/models/file/FileUserProvider.java
@@ -255,22 +255,18 @@ public class FileUserProvider implements UserProvider {
}
@Override
- public List searchForUserByUserAttributes(Map attributes, RealmModel realm) {
+ public List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
Collection users = inMemoryModel.getUsers(realm.getId());
- for (Map.Entry entry : attributes.entrySet()) {
-
- List matchedUsers = new ArrayList<>();
- for (UserModel user : users) {
- List vals = user.getAttribute(entry.getKey());
- if (vals.contains(entry.getValue())) {
- matchedUsers.add(user);
- }
+ List matchedUsers = new ArrayList<>();
+ for (UserModel user : users) {
+ List vals = user.getAttribute(attrName);
+ if (vals.contains(attrValue)) {
+ matchedUsers.add(user);
}
- users = matchedUsers;
}
- return (List) users;
+ return matchedUsers;
}
@Override
diff --git a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java
index a34d70ac45..68b31edb3b 100644
--- a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java
+++ b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheUserProvider.java
@@ -235,8 +235,8 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
}
@Override
- public List searchForUserByUserAttributes(Map attributes, RealmModel realm) {
- return getDelegate().searchForUserByUserAttributes(attributes, realm);
+ public List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
+ return getDelegate().searchForUserByUserAttribute(attrName, attrValue, realm);
}
@Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index c2fab6f776..fc551c7edf 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -1,5 +1,6 @@
package org.keycloak.models.jpa;
+import org.keycloak.connections.jpa.util.JpaUtils;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
@@ -522,7 +523,8 @@ public class ClientAdapter implements ClientModel {
entity.getRoles().remove(role);
entity.getDefaultRoles().remove(role);
- em.createNativeQuery("delete from COMPOSITE_ROLE where CHILD_ROLE = :role").setParameter("role", role).executeUpdate();
+ String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
+ em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", role).executeUpdate();
em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", role).executeUpdate();
role.setClient(null);
em.flush();
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
index 4f02f6c090..d92e93ddea 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
@@ -13,6 +13,7 @@ import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.models.jpa.entities.FederatedIdentityEntity;
+import org.keycloak.models.jpa.entities.UserAttributeEntity;
import org.keycloak.models.jpa.entities.UserEntity;
import org.keycloak.models.utils.CredentialValidation;
import org.keycloak.models.utils.KeycloakModelUtils;
@@ -400,32 +401,15 @@ public class JpaUserProvider implements UserProvider {
}
@Override
- public List searchForUserByUserAttributes(Map attributes, RealmModel realm) {
- StringBuilder builder = new StringBuilder("select attr.user,count(attr.user) from UserAttributeEntity attr where attr.user.realmId = :realmId");
- boolean first = true;
- for (Map.Entry entry : attributes.entrySet()) {
- String attrName = entry.getKey();
- if (first) {
- builder.append(" and ");
- first = false;
- } else {
- builder.append(" or ");
- }
- builder.append(" ( attr.name like :").append(attrName);
- builder.append(" and attr.value like :").append(attrName).append("val )");
- }
- builder.append(" group by attr.user having count(attr.user) = " + attributes.size());
- Query query = em.createQuery(builder.toString());
- query.setParameter("realmId", realm.getId());
- for (Map.Entry entry : attributes.entrySet()) {
- query.setParameter(entry.getKey(), entry.getKey());
- query.setParameter(entry.getKey() + "val", entry.getValue());
- }
- List results = query.getResultList();
+ public List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
+ TypedQuery query = em.createNamedQuery("getAttributesByNameAndValue", UserAttributeEntity.class);
+ query.setParameter("name", attrName);
+ query.setParameter("value", attrValue);
+ List results = query.getResultList();
List users = new ArrayList();
- for (Object o : results) {
- UserEntity user = (UserEntity) ((Object[])o)[0];
+ for (UserAttributeEntity attr : results) {
+ UserEntity user = attr.getUser();
users.add(new UserAdapter(realm, em, user));
}
return users;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 2d099d60ae..6268735339 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -1,5 +1,6 @@
package org.keycloak.models.jpa;
+import org.keycloak.connections.jpa.util.JpaUtils;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel;
@@ -973,7 +974,8 @@ public class RealmAdapter implements RealmModel {
realm.getRoles().remove(roleEntity);
realm.getDefaultRoles().remove(roleEntity);
- em.createNativeQuery("delete from COMPOSITE_ROLE where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
+ String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
+ em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
em.remove(roleEntity);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserAttributeEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserAttributeEntity.java
index 430c796421..ec0eb8614e 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserAttributeEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserAttributeEntity.java
@@ -21,6 +21,7 @@ import java.util.Set;
* @version $Revision: 1 $
*/
@NamedQueries({
+ @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="deleteUserAttributesByRealmAndLink", query="delete from UserAttributeEntity attr where attr.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link)")
})
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
index a433fead56..308d9fb1d4 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
@@ -231,13 +231,10 @@ public class MongoUserProvider implements UserProvider {
}
@Override
- public List searchForUserByUserAttributes(Map attributes, RealmModel realm) {
+ public List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
QueryBuilder queryBuilder = new QueryBuilder()
.and("realmId").is(realm.getId());
-
- for (Map.Entry entry : attributes.entrySet()) {
- queryBuilder.and("attributes." + entry.getKey()).is(entry.getValue());
- }
+ queryBuilder.and("attributes." + attrName).is(attrValue);
List users = getMongoStore().loadEntities(MongoUserEntity.class, queryBuilder.get(), invocationContext);
return convertUserEntities(realm, users);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
index 8fbfdcec78..258dd3cbd7 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
@@ -193,8 +193,8 @@ public class UserModelTest extends AbstractModelTest {
Assert.assertEquals("val23", attrVals.get(0));
}
- // @Test
- public void testSearchByUserAttributes() throws Exception {
+ @Test
+ public void testSearchByUserAttribute() throws Exception {
RealmModel realm = realmManager.createRealm("original");
UserModel user1 = session.users().addUser(realm, "user1");
UserModel user2 = session.users().addUser(realm, "user2");
@@ -210,20 +210,21 @@ public class UserModelTest extends AbstractModelTest {
commit();
- Map attributes = new HashMap();
- attributes.put("key1", "value1");
- List users = session.users().searchForUserByUserAttributes(attributes, realm);
+ List users = session.users().searchForUserByUserAttribute("key1", "value1", realm);
Assert.assertEquals(2, users.size());
Assert.assertTrue(users.contains(user1));
Assert.assertTrue(users.contains(user2));
- attributes.put("key2", "value21");
- users = session.users().searchForUserByUserAttributes(attributes, realm);
- Assert.assertEquals(1, users.size());
+ users = session.users().searchForUserByUserAttribute("key2", "value21", realm);
+ Assert.assertEquals(2, users.size());
Assert.assertTrue(users.contains(user1));
+ Assert.assertTrue(users.contains(user3));
- attributes.put("key3", "value3");
- users = session.users().searchForUserByUserAttributes(attributes, realm);
+ users = session.users().searchForUserByUserAttribute("key2", "value22", realm);
+ Assert.assertEquals(1, users.size());
+ Assert.assertTrue(users.contains(user2));
+
+ users = session.users().searchForUserByUserAttribute("key3", "value3", realm);
Assert.assertEquals(0, users.size());
}