From 493fd0ad6ab64853cbe7aacb64ce85efb636e857 Mon Sep 17 00:00:00 2001 From: mposolda Date: Thu, 3 Sep 2015 11:15:06 +0200 Subject: [PATCH] KEYCLOAK-1760 Fix DB issues when schema option defined --- .../LiquibaseJpaUpdaterProvider.java | 2 +- .../liquibase/custom/AddRealmCodeSecret.java | 3 ++- .../liquibase/custom/CustomKeycloakTask.java | 8 +++++++- .../custom/JpaUpdate1_2_0_Beta1.java | 19 ++++++++++++------- .../liquibase/custom/JpaUpdate1_2_0_CR1.java | 2 +- .../custom/JpaUpdate1_4_0_Final.java | 2 +- .../META-INF/jpa-changelog-1.5.0.xml | 5 +++++ .../DefaultJpaConnectionProviderFactory.java | 3 ++- .../connections/jpa/util/JpaUtils.java | 16 ++++++++++++++++ .../keycloak/models/jpa/ClientAdapter.java | 4 +++- .../org/keycloak/models/jpa/RealmAdapter.java | 4 +++- 11 files changed, 53 insertions(+), 15 deletions(-) create mode 100644 connections/jpa/src/main/java/org/keycloak/connections/jpa/util/JpaUtils.java 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/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/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);