8000 Preserve database metadata in custom Hibernate dialects by ahus1 · Pull Request #54511 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.sql.ast.H2SqlAstTranslator;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
Expand All @@ -35,6 +36,14 @@
*/
public class KeycloakH2Dialect extends H2Dialect {

public KeycloakH2Dialect() {
super();
}

public KeycloakH2Dialect(DialectResolutionInfo info) {
super(info);
}

@Override
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
return new StandardSqlAstTranslatorFactory() {
Expand Down
< 8000 /table>
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.sql.ast.OracleSqlAstTranslator;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
Expand All @@ -41,6 +42,14 @@
*/
public class KeycloakOracleDialect extends OracleDialect {

public KeycloakOracleDialect() {
super();
}

public KeycloakOracleDialect(DialectResolutionInfo info) {
super(info);
}

@Override
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
return new StandardSqlAstTranslatorFactory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.hibernate.LockMode;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.sql.ast.SQLServerSqlAstTranslator;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
Expand All @@ -40,6 +41,14 @@
*/
public class KeycloakSQLServerDialect extends SQLServerDialect {

public KeycloakSQLServerDialect() {
super();
}

public KeycloakSQLServerDialect(DialectResolutionInfo info) {
super(info);
}

@Override
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
return new StandardSqlAstTranslatorFactory() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2026 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.keycloak.connections.jpa.dialect;

import java.util.List;

import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import static org.junit.Assert.assertEquals;

@RunWith(Parameterized.class)
public class KeycloakDialectTest {
@Parameterized.Parameters(name = "{0}")
public static List<Class<? extends Dialect>> dialects() {
return List.of(KeycloakH2Dialect.class, KeycloakOracleDialect.class, KeycloakSQLServerDialect.class);
}

@Parameterized.Parameter
public Class<? extends Dialect> dialect;

@Test
public void exposesPublicConstructorsUsedByHibernate() throws Exception {
// Constructors are not inherited. Hibernate falls back to no-argument construction
// when the dialect does not expose the metadata constructor, losing database capabilities.
assertEquals(dialect, dialect.getConstructor(DialectResolutionInfo.class).getDeclaringClass());
assertEquals(dialect, dialect.getConstructor().getDeclaringClass());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2026 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.keycloak.connections.jpa.dialect;

import java.sql.DriverManager;

import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.jboss.logging.Logger;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class KeycloakH2DialectTest {
private static final Logger LOG = Logger.getLogger(KeycloakH2DialectTest.class);

@Test
public void hibernatePassesDetectedDatabaseVersionToDialect() throws Exception {
String url = "jdbc:h2:mem:dialect-version";
var registry = new StandardServiceRegistryBuilder()
.applySetting("hibernate.connection.url", url)
.applySetting("hibernate.connection.username", "sa")
.applySetting("hibernate.connection.password", "")
.applySetting("hibernate.dialect", KeycloakH2Dialect.class.getName())
.build();
try (var connection = DriverManager.getConnection(url, "sa", "")) {
var metadata = connection.getMetaData();
var dialect = registry.getService(JdbcEnvironment.class).getDialect();
var version = dialect.getVersion();
LOG.infof("H2 database version: %s; identified dialect version: %s",
metadata.getDatabaseProductVersion(), version);
assertEquals(KeycloakH2Dialect.class, dialect.getClass());
assertEquals(metadata.getDatabaseMajorVersion(), version.getDatabaseMajorVersion());
assertEquals(metadata.getDatabaseMinorVersion(), version.getDatabaseMinorVersion());
// H2 includes the patch version followed by its release date in JDBC metadata.
String patch = metadata.getDatabaseProductVersion().split("[. ]")[2];
assertEquals(Integer.parseInt(patch), version.getDatabaseMicroVersion());
} finally {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
Loading
0