KEYCLOAK-2601 Fix incorrectly autodetected dialect with MSSQL2014

This commit is contained in:
mposolda 2016-03-09 11:55:55 +01:00
parent 321b23a78d
commit 583f8ad739
3 changed files with 62 additions and 9 deletions

View file

@ -220,8 +220,8 @@ bin/add-user-keycloak.[sh|bat] -r master -u <username> -p <password>
<title>Tested databases</title>
<para>
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 <literal>driverDialect</literal>
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 <literal>driverDialect</literal>
to the <literal>keycloak-server.json</literal> into <literal>connectionsJpa</literal> section (see above).
<table frame='all'><title>Tested databases</title>
<tgroup cols='3' align='left' colsep='1' rowsep='1'>
@ -261,7 +261,7 @@ bin/add-user-keycloak.[sh|bat] -r master -u <username> -p <password>
<row>
<entry>Microsoft SQL Server 2012</entry>
<entry>Microsoft SQL Server JDBC Driver 4.0.2206.100</entry>
<entry>org.hibernate.dialect.SQLServer2008Dialect</entry>
<entry>auto</entry>
</row>
<row>
<entry>IBM DB2 10.5</entry>

View file

@ -121,11 +121,6 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
}
}
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 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
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 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
}
}
}
protected void prepareOperationalInfo(Connection connection) {
try {
operationalInfo = new LinkedHashMap<>();
@ -225,6 +225,42 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
}
}
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 {

View file

@ -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 @@ import java.util.Map;
*/
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 class UserModelTest extends AbstractModelTest {
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<UserModel> users = session.users().searchForUser("user", realm, 0, 7);
Assert.assertTrue(users.contains(user1));
}
@Test
public void testSearchByUserAttribute() throws Exception {
RealmModel realm = realmManager.createRealm("original");