diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml b/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml index 6ab7b5aaad5..9d3237d50d3 100755 --- a/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml +++ b/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml @@ -220,8 +220,8 @@ bin/add-user-keycloak.[sh|bat] -r master -u -p Tested databases Here is list of RDBMS databases and corresponding JDBC drivers, which were tested with Keycloak. Note that Hibernate dialect - is usually set automatically according to your database, but in some cases, you must manually set the proper dialect, - as the default dialect may not work correctly. You can setup dialect by adding property driverDialect + is usually set automatically according to your database, but you have possibility to override if default dialect doesn't work correctly. + You can setup dialect by adding property driverDialect to the keycloak-server.json into connectionsJpa section (see above). Tested databases @@ -261,7 +261,7 @@ bin/add-user-keycloak.[sh|bat] -r master -u -p Microsoft SQL Server 2012 Microsoft SQL Server JDBC Driver 4.0.2206.100 - org.hibernate.dialect.SQLServer2008Dialect + auto IBM DB2 10.5 diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java index 268c3c8cd02..444e891031c 100755 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java @@ -121,11 +121,6 @@ private void lazyInit(KeycloakSession session) { } } - String driverDialect = config.get("driverDialect"); - if (driverDialect != null && driverDialect.length() > 0) { - properties.put("hibernate.dialect", driverDialect); - } - String schema = getSchema(); if (schema != null) { properties.put(JpaUtils.HIBERNATE_DEFAULT_SCHEMA, schema); @@ -147,6 +142,11 @@ private void lazyInit(KeycloakSession session) { connection = getConnection(); try{ prepareOperationalInfo(connection); + + String driverDialect = detectDialect(connection); + if (driverDialect != null) { + properties.put("hibernate.dialect", driverDialect); + } if (databaseSchema != null) { logger.trace("Updating database"); @@ -209,7 +209,7 @@ private void lazyInit(KeycloakSession session) { } } } - + protected void prepareOperationalInfo(Connection connection) { try { operationalInfo = new LinkedHashMap<>(); @@ -225,6 +225,42 @@ protected void prepareOperationalInfo(Connection connection) { } } + + protected String detectDialect(Connection connection) { + String driverDialect = config.get("driverDialect"); + if (driverDialect != null && driverDialect.length() > 0) { + return driverDialect; + } else { + try { + String dbProductName = connection.getMetaData().getDatabaseProductName(); + String dbProductVersion = connection.getMetaData().getDatabaseProductVersion(); + + // For MSSQL2014, we may need to fix the autodetected dialect by hibernate + if (dbProductName.equals("Microsoft SQL Server")) { + String topVersionStr = dbProductVersion.split("\\.")[0]; + boolean shouldSet2012Dialect = true; + try { + int topVersion = Integer.parseInt(topVersionStr); + if (topVersion < 12) { + shouldSet2012Dialect = false; + } + } catch (NumberFormatException nfe) { + } + if (shouldSet2012Dialect) { + String sql2012Dialect = "org.hibernate.dialect.SQLServer2012Dialect"; + logger.debugf("Manually override hibernate dialect to %s", sql2012Dialect); + return sql2012Dialect; + } + } + } catch (SQLException e) { + logger.warnf("Unable to detect hibernate dialect due database exception : %s", e.getMessage()); + } + + return null; + } + } + + @Override public Connection getConnection() { try { 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 53c313f9a2d..fc8a476903d 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 @@ -17,8 +17,10 @@ package org.keycloak.testsuite.model; +import org.jboss.logging.Logger; import org.junit.Assert; import org.junit.Test; +import org.keycloak.Config; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -40,6 +42,8 @@ */ public class UserModelTest extends AbstractModelTest { + private static final Logger logger = Logger.getLogger(UserModelTest.class); + @Test public void persistUser() { RealmModel realm = realmManager.createRealm("original"); @@ -211,6 +215,19 @@ public void testUserMultipleAttributes() throws Exception { Assert.assertEquals("val23", attrVals.get(0)); } + @Test + public void testSearchByString() { + logger.infof("Started testSearchByString"); + RealmModel realm = realmManager.getRealmByName("test"); + UserModel user1 = session.users().addUser(realm, "user1"); + logger.infof("Added user1"); + + commit(); + + List users = session.users().searchForUser("user", realm, 0, 7); + Assert.assertTrue(users.contains(user1)); + } + @Test public void testSearchByUserAttribute() throws Exception { RealmModel realm = realmManager.createRealm("original");