HHH-14478 : Allow DialectResolvers to be discovered by ServiceLoader

This commit is contained in:
Steve Ebersole 2021-03-05 14:42:21 -06:00
parent 47f7ca7ff5
commit 69564cd7c8
18 changed files with 272 additions and 164 deletions

View File

@ -15,6 +15,7 @@ import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.spi.TimestampsCacheFactory;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
import org.hibernate.query.hql.HqlTranslator;
@ -427,6 +428,59 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
*/
String DIALECT_RESOLVERS = "hibernate.dialect_resolvers";
/**
* Specifies the name of the database provider in cases where a Connection to the underlying database is
* not available (aka, mainly in generating scripts). In such cases, a value for this setting
* *must* be specified.
* <p/>
* The value of this setting is expected to match the value returned by
* {@link java.sql.DatabaseMetaData#getDatabaseProductName()} for the target database.
* <p/>
* Additionally specifying {@value #DIALECT_DB_MAJOR_VERSION} and/or {@value #DIALECT_DB_MINOR_VERSION}
* may be required to understand exactly how to generate the required schema commands.
*
* @see #DIALECT_DB_VERSION
* @see #DIALECT_DB_MAJOR_VERSION
* @see #DIALECT_DB_MINOR_VERSION
*/
String DIALECT_DB_NAME = "javax.persistence.database-product-name";
/**
* Specifies the name of the database provider in cases where a Connection to the underlying database is
* not available (aka, mainly in generating scripts). This value is used to help more precisely determine
* how to perform schema generation tasks for the underlying database in cases where
* {@value #DIALECT_DB_NAME} does not provide enough distinction.
* <p/>
* The value of this setting is expected to match the value returned by
* {@link java.sql.DatabaseMetaData#getDatabaseProductVersion()} for the target database.
*
* @see #DIALECT_DB_NAME
*/
String DIALECT_DB_VERSION = "javax.persistence.database-product-version";
/**
* Specifies the major version of the underlying database, as would be returned by
* {@link java.sql.DatabaseMetaData#getDatabaseMajorVersion} for the target database. This value is used to
* help more precisely determine how to perform schema generation tasks for the underlying database in cases
* where {@value #DIALECT_DB_NAME} does not provide enough distinction.
* @see #DIALECT_DB_NAME
* @see #DIALECT_DB_MINOR_VERSION
*/
String DIALECT_DB_MAJOR_VERSION = "javax.persistence.database-major-version";
/**
* Specifies the minor version of the underlying database, as would be returned by
* {@link java.sql.DatabaseMetaData#getDatabaseMinorVersion} for the target database.
*
* This setting is used in Dialect resolution
*
* @see #DIALECT_DB_NAME
* @see #DIALECT_DB_MAJOR_VERSION
* @see DialectResolver
*/
String DIALECT_DB_MINOR_VERSION = "javax.persistence.database-minor-version";
/**
* Defines the default storage engine for the relational databases that support multiple storage engines.
* This property must be set either as an Environment variable or JVM System Property.
@ -1356,63 +1410,33 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
/**
* Allows passing a specific {@link java.sql.Connection} instance to be used by SchemaManagementTool.
* <p/>
* May also be used to determine the values for {@value #HBM2DDL_DB_NAME},
* {@value #HBM2DDL_DB_MAJOR_VERSION} and {@value #HBM2DDL_DB_MINOR_VERSION}.
* May also be used to determine the values for {@value #DIALECT_DB_NAME},
* {@value #DIALECT_DB_MAJOR_VERSION} and {@value #DIALECT_DB_MINOR_VERSION}.
*/
String HBM2DDL_CONNECTION = "javax.persistence.schema-generation-connection";
/**
* Specifies the name of the database provider in cases where a Connection to the underlying database is
* not available (aka, mainly in generating scripts). In such cases, a value for this setting
* *must* be specified.
* <p/>
* The value of this setting is expected to match the value returned by
* {@link java.sql.DatabaseMetaData#getDatabaseProductName()} for the target database.
* <p/>
* Additionally specifying {@value #HBM2DDL_DB_MAJOR_VERSION} and/or {@value #HBM2DDL_DB_MINOR_VERSION}
* may be required to understand exactly how to generate the required schema commands.
*
* @see #HBM2DDL_DB_MAJOR_VERSION
* @see #HBM2DDL_DB_MINOR_VERSION
* @deprecated Use {@link #DIALECT_DB_NAME} instead
*/
@SuppressWarnings("JavaDoc")
String HBM2DDL_DB_NAME = "javax.persistence.database-product-name";
@Deprecated
String HBM2DDL_DB_NAME = DIALECT_DB_NAME;
/**
* Specifies the name of the database provider in cases where a Connection to the underlying database is
* not available (aka, mainly in generating scripts). This value is used to help more precisely determine
* how to perform schema generation tasks for the underlying database in cases where
* {@value #HBM2DDL_DB_NAME} does not provide enough distinction.
* <p/>
* The value of this setting is expected to match the value returned by
* {@link java.sql.DatabaseMetaData#getDatabaseProductVersion()} for the target database.
*
* @see #HBM2DDL_DB_NAME
* @deprecated Use {@link #DIALECT_DB_VERSION} instead
*/
@SuppressWarnings("JavaDoc")
@Deprecated
String HBM2DDL_DB_VERSION = "javax.persistence.database-product-version";
/**
* Specifies the major version of the underlying database, as would be returned by
* {@link java.sql.DatabaseMetaData#getDatabaseMajorVersion} for the target database. This value is used to
* help more precisely determine how to perform schema generation tasks for the underlying database in cases
* where {@value #HBM2DDL_DB_NAME} does not provide enough distinction.
* @see #HBM2DDL_DB_NAME
* @see #HBM2DDL_DB_MINOR_VERSION
* @deprecated Use {@link #DIALECT_DB_MAJOR_VERSION} instead
*/
@Deprecated
String HBM2DDL_DB_MAJOR_VERSION = "javax.persistence.database-major-version";
/**
* Specifies the minor version of the underlying database, as would be returned by
* {@link java.sql.DatabaseMetaData#getDatabaseMinorVersion} for the target database. This value is used to
* help more precisely determine how to perform schema generation tasks for the underlying database in cases
* where the combination of {@value #HBM2DDL_DB_NAME} and {@value #HBM2DDL_DB_MAJOR_VERSION} does not provide
* enough distinction.
*
* @see #HBM2DDL_DB_NAME
* @see #HBM2DDL_DB_MAJOR_VERSION
* @deprecated Use {@link #DIALECT_DB_MINOR_VERSION} instead
*/
@Deprecated
String HBM2DDL_DB_MINOR_VERSION = "javax.persistence.database-minor-version";
/**

View File

@ -14,6 +14,8 @@ import java.sql.Statement;
import org.hibernate.engine.jdbc.dialect.spi.BasicSQLExceptionConverter;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import static org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo.NO_VERSION;
/**
* A list of relational database systems for which Hibernate can resolve a {@link Dialect}.
*
@ -55,20 +57,25 @@ public enum Database {
@Override
public Dialect createDialect(DialectResolutionInfo info) {
String databaseVersion = info.getDatabaseVersion();
if ( databaseVersion == null ) {
return new DB2Dialect( info );
}
//See https://www.ibm.com/support/knowledgecenter/SSEPEK_12.0.0/java/src/tpc/imjcc_c0053013.html
switch ( databaseVersion.substring( 0, 3 ) ) {
case "SQL": // Linux, UNIX, Windows
return new DB2Dialect( info );
case "DSN": // z/OS
return new DB2zDialect( info );
case "QSQ": // i
return new DB2iDialect( info );
default:
return null;
if ( databaseVersion != null ) {
//See https://www.ibm.com/support/knowledgecenter/SSEPEK_12.0.0/java/src/tpc/imjcc_c0053013.html
switch ( databaseVersion.substring( 0, 3 ) ) {
case "SQL": {
// Linux, UNIX, Windows
return new DB2Dialect( info );
}
case "DSN": {
// z/OS
return new DB2zDialect( info );
}
case "QSQ": {
// i
return new DB2iDialect( info );
}
}
}
return new DB2Dialect( info );
}
@Override
public boolean productNameMatches(String databaseName) {
@ -332,15 +339,18 @@ public enum Database {
return "org.postgresql.Driver";
}
private String getVersion(DatabaseMetaData databaseMetaData) {
try (Statement statement = databaseMetaData.getConnection().createStatement() ) {
final ResultSet rs = statement.executeQuery( "select version()" );
if ( rs.next() ) {
return rs.getString( 1 );
if ( databaseMetaData != null ) {
try ( Statement statement = databaseMetaData.getConnection().createStatement() ) {
final ResultSet rs = statement.executeQuery( "select version()" );
if ( rs.next() ) {
return rs.getString( 1 );
}
}
catch (SQLException e) {
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
}
}
catch (SQLException e) {
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
}
return "";
}
},

View File

@ -127,7 +127,12 @@ public class H2Dialect extends Dialect {
}
private static int parseBuildId(DialectResolutionInfo info) {
String[] bits = info.getDatabaseVersion().split("[. ]");
final String databaseVersion = info.getDatabaseVersion();
if ( databaseVersion == null ) {
return 0;
}
final String[] bits = databaseVersion.split("[. ]");
return bits.length > 2 ? Integer.parseInt( bits[2] ) : 0;
}

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.engine.jdbc.dialect.internal;
import java.util.Collection;
import java.util.Map;
import org.hibernate.HibernateException;
@ -18,7 +19,7 @@ import org.hibernate.service.spi.ServiceException;
import org.hibernate.service.spi.ServiceRegistryImplementor;
/**
* Standard initiator for the standard {@link DialectResolver} service
* Standard initiator for the {@link DialectResolver} service
*
* @author Steve Ebersole
*/
@ -36,25 +37,25 @@ public class DialectResolverInitiator implements StandardServiceInitiator<Dialec
@Override
public DialectResolver initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
final DialectResolverSet resolver = new DialectResolverSet();
final DialectResolverSet resolverSet = new DialectResolverSet();
applyCustomerResolvers( resolver, registry, configurationValues );
resolver.addResolver( new StandardDialectResolver() );
applyCustomerResolvers( resolverSet, registry, configurationValues );
resolverSet.addResolver( new StandardDialectResolver() );
return resolver;
return resolverSet;
}
private void applyCustomerResolvers(
DialectResolverSet resolver,
DialectResolverSet resolverSet,
ServiceRegistryImplementor registry,
Map configurationValues) {
Map<?,?> configurationValues) {
final String resolverImplNames = (String) configurationValues.get( AvailableSettings.DIALECT_RESOLVERS );
final ClassLoaderService classLoaderService = registry.getService( ClassLoaderService.class );
if ( StringHelper.isNotEmpty( resolverImplNames ) ) {
final ClassLoaderService classLoaderService = registry.getService( ClassLoaderService.class );
for ( String resolverImplName : StringHelper.split( ", \n\r\f\t", resolverImplNames ) ) {
try {
resolver.addResolver(
resolverSet.addResolver(
(DialectResolver) classLoaderService.classForName( resolverImplName ).newInstance()
);
}
@ -66,5 +67,8 @@ public class DialectResolverInitiator implements StandardServiceInitiator<Dialec
}
}
}
final Collection<DialectResolver> resolvers = classLoaderService.loadJavaServices( DialectResolver.class );
resolverSet.addDiscoveredResolvers( resolvers );
}
}

View File

@ -8,6 +8,7 @@ package org.hibernate.engine.jdbc.dialect.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.hibernate.dialect.Dialect;
@ -60,23 +61,15 @@ public class DialectResolverSet implements DialectResolver {
return null;
}
/**
* Add a resolver at the end of the underlying resolver list. The resolver added by this method is at lower
* priority than any other existing resolvers.
*
* @param resolver The resolver to add.
*/
public void addResolver(DialectResolver resolver) {
resolvers.add( resolver );
public void addResolver(DialectResolver... resolvers) {
this.resolvers.addAll( Arrays.asList( resolvers ) );
}
/**
* Add a resolver at the beginning of the underlying resolver list. The resolver added by this method is at higher
* priority than any other existing resolvers.
*
* @param resolver The resolver to add.
*/
public void addResolverAtFirst(DialectResolver resolver) {
resolvers.add( 0, resolver );
public void addResolverAtFirst(DialectResolver... resolvers) {
this.resolvers.addAll( 0, Arrays.asList( resolvers ) );
}
public void addDiscoveredResolvers(Collection<DialectResolver> resolvers) {
this.resolvers.addAll( 0, resolvers );
}
}

View File

@ -17,6 +17,8 @@ import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
* @author Steve Ebersole
*/
public final class StandardDialectResolver implements DialectResolver {
public StandardDialectResolver() {
}
@Override
public Dialect resolveDialect(DialectResolutionInfo info) {

View File

@ -12,14 +12,12 @@ package org.hibernate.engine.jdbc.dialect.spi;
* <p/>
* The information here mimics part of the JDBC {@link java.sql.DatabaseMetaData} contract, specifically the portions
* about database and driver names and versions.
*
* @author Steve Ebersole
*/
public interface DialectResolutionInfo {
/**
* Constant used to indicate that no version is defined
*/
public static final int NO_VERSION = -9999;
int NO_VERSION = -9999;
/**
* Obtain access to the database name, as returned from {@link java.sql.DatabaseMetaData#getDatabaseProductName()}
@ -29,7 +27,7 @@ public interface DialectResolutionInfo {
*
* @see java.sql.DatabaseMetaData#getDatabaseProductName()
*/
public String getDatabaseName();
String getDatabaseName();
/**
* Obtain access to the database version, as returned from {@link java.sql.DatabaseMetaData#getDatabaseProductVersion()}
@ -39,7 +37,7 @@ public interface DialectResolutionInfo {
*
* @see java.sql.DatabaseMetaData#getDatabaseProductVersion()
*/
public String getDatabaseVersion();
String getDatabaseVersion();
/**
* Obtain access to the database major version, as returned from
@ -49,7 +47,7 @@ public interface DialectResolutionInfo {
*
* @see java.sql.DatabaseMetaData#getDatabaseMajorVersion()
*/
public int getDatabaseMajorVersion();
int getDatabaseMajorVersion();
/**
* Obtain access to the database minor version, as returned from
@ -59,7 +57,7 @@ public interface DialectResolutionInfo {
*
* @see java.sql.DatabaseMetaData#getDatabaseMinorVersion()
*/
public int getDatabaseMinorVersion();
int getDatabaseMinorVersion();
/**
* Obtain access to the name of the JDBC driver, as returned from {@link java.sql.DatabaseMetaData#getDriverName()}
@ -69,7 +67,7 @@ public interface DialectResolutionInfo {
*
* @see java.sql.DatabaseMetaData#getDriverName()
*/
public String getDriverName();
String getDriverName();
/**
* Obtain access to the major version of the JDBC driver, as returned from
@ -79,7 +77,7 @@ public interface DialectResolutionInfo {
*
* @see java.sql.DatabaseMetaData#getDriverMajorVersion()
*/
public int getDriverMajorVersion();
int getDriverMajorVersion();
/**
* Obtain access to the minor version of the JDBC driver, as returned from
@ -89,7 +87,7 @@ public interface DialectResolutionInfo {
*
* @see java.sql.DatabaseMetaData#getDriverMinorVersion()
*/
public int getDriverMinorVersion();
int getDriverMinorVersion();
/**
* Obtain access to the underlying object of the given type.

View File

@ -8,14 +8,11 @@ package org.hibernate.engine.jdbc.dialect.spi;
/**
* Contract for the source of DialectResolutionInfo.
*
* @author Steve Ebersole
*/
@FunctionalInterface
public interface DialectResolutionInfoSource {
/**
* Get the DialectResolutionInfo
*
* @return The DialectResolutionInfo
*/
public DialectResolutionInfo getDialectResolutionInfo();
DialectResolutionInfo getDialectResolutionInfo();
}

View File

@ -62,28 +62,28 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
true
);
if ( configurationValues.containsKey( AvailableSettings.HBM2DDL_DB_NAME ) ) {
if ( configurationValues.containsKey( AvailableSettings.DIALECT_DB_NAME ) ) {
return new JdbcEnvironmentImpl( registry, dialectFactory.buildDialect(
configurationValues,
() -> new DialectResolutionInfo() {
@Override
public String getDatabaseName() {
return (String) configurationValues.get( AvailableSettings.HBM2DDL_DB_NAME );
return (String) configurationValues.get( AvailableSettings.DIALECT_DB_NAME );
}
@Override
public String getDatabaseVersion() {
return (String) configurationValues.getOrDefault( AvailableSettings.HBM2DDL_DB_VERSION, "0" );
return (String) configurationValues.getOrDefault( AvailableSettings.DIALECT_DB_VERSION, "0" );
}
@Override
public int getDatabaseMajorVersion() {
return (Integer) configurationValues.getOrDefault( AvailableSettings.HBM2DDL_DB_MAJOR_VERSION, 0 );
return (Integer) configurationValues.getOrDefault( AvailableSettings.DIALECT_DB_MAJOR_VERSION, 0 );
}
@Override
public int getDatabaseMinorVersion() {
return (Integer) configurationValues.getOrDefault( AvailableSettings.HBM2DDL_DB_MINOR_VERSION, 0 );
return (Integer) configurationValues.getOrDefault( AvailableSettings.DIALECT_DB_MINOR_VERSION, 0 );
}
@Override

View File

@ -200,22 +200,22 @@ public interface AvailableSettings {
String SCHEMA_GEN_CONNECTION = org.hibernate.cfg.AvailableSettings.HBM2DDL_CONNECTION;
/**
* @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_NAME} instead
* @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#DIALECT_DB_NAME} instead
*/
@Deprecated
String SCHEMA_GEN_DB_NAME = org.hibernate.cfg.AvailableSettings.HBM2DDL_DB_NAME;
String SCHEMA_GEN_DB_NAME = org.hibernate.cfg.AvailableSettings.DIALECT_DB_NAME;
/**
* @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_MAJOR_VERSION} instead
* @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#DIALECT_DB_MAJOR_VERSION} instead
*/
@Deprecated
String SCHEMA_GEN_DB_MAJOR_VERSION = org.hibernate.cfg.AvailableSettings.HBM2DDL_DB_MAJOR_VERSION;
String SCHEMA_GEN_DB_MAJOR_VERSION = org.hibernate.cfg.AvailableSettings.DIALECT_DB_MAJOR_VERSION;
/**
* @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_MINOR_VERSION} instead
* @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#DIALECT_DB_MINOR_VERSION} instead
*/
@Deprecated
String SCHEMA_GEN_DB_MINOR_VERSION = org.hibernate.cfg.AvailableSettings.HBM2DDL_DB_MINOR_VERSION;
String SCHEMA_GEN_DB_MINOR_VERSION = org.hibernate.cfg.AvailableSettings.DIALECT_DB_MINOR_VERSION;
/**
* @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_LOAD_SCRIPT_SOURCE} instead

View File

@ -198,11 +198,11 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv
}
// see if a specific Dialect override has been provided...
final String explicitDbName = (String) configurationValues.get( AvailableSettings.HBM2DDL_DB_NAME );
final String explicitDbName = (String) configurationValues.get( AvailableSettings.DIALECT_DB_NAME );
if ( StringHelper.isNotEmpty( explicitDbName ) ) {
final String explicitDbVersion = (String) configurationValues.get( AvailableSettings.HBM2DDL_DB_VERSION );
final String explicitDbMajor = (String) configurationValues.get( AvailableSettings.HBM2DDL_DB_MAJOR_VERSION );
final String explicitDbMinor = (String) configurationValues.get( AvailableSettings.HBM2DDL_DB_MINOR_VERSION );
final String explicitDbVersion = (String) configurationValues.get( AvailableSettings.DIALECT_DB_VERSION );
final String explicitDbMajor = (String) configurationValues.get( AvailableSettings.DIALECT_DB_MAJOR_VERSION );
final String explicitDbMinor = (String) configurationValues.get( AvailableSettings.DIALECT_DB_MINOR_VERSION );
final Dialect indicatedDialect = serviceRegistry.getService( DialectResolver.class ).resolveDialect(
new DialectResolutionInfo() {

View File

@ -57,4 +57,4 @@ for details.
Complete Hibernate documentation may be found online at <a href="http://docs.jboss.org/hibernate/">http://docs.jboss.org/hibernate/</a>.
</body>
</body>

View File

@ -7,7 +7,7 @@
package org.hibernate.engine.jdbc.dialect.internal;
import org.hibernate.dialect.*;
import org.hibernate.dialect.resolver.TestingDialectResolutionInfo;
import org.hibernate.orm.test.dialect.resolver.TestingDialectResolutionInfo;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect.resolver;
package org.hibernate.orm.test.dialect.resolver;
import org.hibernate.HibernateException;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
@ -109,42 +109,42 @@ public class DialectFactoryTest extends BaseUnitTestCase {
testDetermination( "HSQL Database Engine", HSQLDialect.class, resolver );
testDetermination( "H2", H2Dialect.class, resolver );
testDetermination( "MySQL", MySQLDialect.class, resolver );
testDetermination( "MySQL", 5, 0, MySQL5Dialect.class, resolver );
testDetermination( "MySQL", 5, 5, MySQL55Dialect.class, resolver );
testDetermination( "MySQL", 5, 6, MySQL55Dialect.class, resolver );
testDetermination( "MySQL", 5, 7, MySQL57Dialect.class, resolver );
testDetermination( "MySQL", 8, 0, MySQL8Dialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 10, 3, MariaDB103Dialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 10, 2, MariaDB102Dialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 10, 1, MariaDB10Dialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 10, 0, MariaDB10Dialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 5, 5, MariaDB53Dialect.class, resolver );
testDetermination( "MySQL", 5, 0, MySQLDialect.class, resolver );
testDetermination( "MySQL", 5, 5, MySQLDialect.class, resolver );
testDetermination( "MySQL", 5, 6, MySQLDialect.class, resolver );
testDetermination( "MySQL", 5, 7, MySQLDialect.class, resolver );
testDetermination( "MySQL", 8, 0, MySQLDialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 10, 3, MariaDBDialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 10, 2, MariaDBDialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 10, 1, MariaDBDialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 10, 0, MariaDBDialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 5, 5, MariaDBDialect.class, resolver );
testDetermination( "MariaDB", "MariaDB connector/J", 5, 2, MariaDBDialect.class, resolver );
testDetermination( "PostgreSQL", PostgreSQL81Dialect.class, resolver );
testDetermination( "PostgreSQL", 8, 2, PostgreSQL82Dialect.class, resolver );
testDetermination( "PostgreSQL", 8, 3, PostgreSQL82Dialect.class, resolver );
testDetermination( "PostgreSQL", 9, 0, PostgreSQL9Dialect.class, resolver );
testDetermination( "PostgreSQL", 9, 1, PostgreSQL9Dialect.class, resolver );
testDetermination( "PostgreSQL", 9, 2, PostgreSQL92Dialect.class, resolver );
testDetermination( "PostgreSQL", 9, 3, PostgreSQL92Dialect.class, resolver );
testDetermination( "PostgreSQL", 9, 4, PostgreSQL94Dialect.class, resolver );
testDetermination( "PostgreSQL", 9, 5, PostgreSQL95Dialect.class, resolver );
testDetermination( "PostgreSQL", 9, 6, PostgreSQL95Dialect.class, resolver );
testDetermination( "PostgreSQL", PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 8, 2, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 8, 3, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 9, 0, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 9, 1, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 9, 2, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 9, 3, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 9, 4, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 9, 5, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 9, 6, PostgreSQLDialect.class, resolver );
testDetermination( "PostgreSQL", 10, 0, PostgreSQLDialect.class, resolver );
testDetermination( "EnterpriseDB", 9, 2, PostgresPlusDialect.class, resolver );
testDetermination( "Apache Derby", 10, 4, DerbyDialect.class, resolver );
testDetermination( "Apache Derby", 10, 5, DerbyTenFiveDialect.class, resolver );
testDetermination( "Apache Derby", 10, 6, DerbyTenSixDialect.class, resolver );
testDetermination( "Apache Derby", 11, 5, DerbyTenSevenDialect.class, resolver );
testDetermination( "Apache Derby", 10, 5, DerbyDialect.class, resolver );
testDetermination( "Apache Derby", 10, 6, DerbyDialect.class, resolver );
testDetermination( "Apache Derby", 11, 5, DerbyDialect.class, resolver );
testDetermination( "Ingres", IngresDialect.class, resolver );
testDetermination( "ingres", IngresDialect.class, resolver );
testDetermination( "INGRES", IngresDialect.class, resolver );
testDetermination( "Microsoft SQL Server Database", SQLServerDialect.class, resolver );
testDetermination( "Microsoft SQL Server", SQLServerDialect.class, resolver );
testDetermination( "Sybase SQL Server", SybaseASE15Dialect.class, resolver );
testDetermination( "Adaptive Server Enterprise", SybaseASE15Dialect.class, resolver );
testDetermination( "Sybase SQL Server", SybaseASEDialect.class, resolver );
testDetermination( "Adaptive Server Enterprise", SybaseASEDialect.class, resolver );
testDetermination( "Adaptive Server Anywhere", SybaseAnywhereDialect.class, resolver );
testDetermination( "Informix Dynamic Server", Informix10Dialect.class, resolver );
testDetermination( "Informix Dynamic Server", InformixDialect.class, resolver );
testDetermination( "DB2/NT", DB2Dialect.class, resolver );
testDetermination( "DB2/LINUX", DB2Dialect.class, resolver );
testDetermination( "DB2/6000", DB2Dialect.class, resolver );
@ -152,12 +152,12 @@ public class DialectFactoryTest extends BaseUnitTestCase {
testDetermination( "DB2/SUN", DB2Dialect.class, resolver );
testDetermination( "DB2/LINUX390", DB2Dialect.class, resolver );
testDetermination( "DB2/AIX64", DB2Dialect.class, resolver );
testDetermination( "DB2 UDB for AS/400", DB2400Dialect.class, resolver );
testDetermination( "DB2 UDB for AS/400", 7, 3, DB2400V7R3Dialect.class, resolver );
testDetermination( "Oracle", 8, Oracle8iDialect.class, resolver );
testDetermination( "Oracle", 9, Oracle9iDialect.class, resolver );
testDetermination( "Oracle", 10, Oracle10gDialect.class, resolver );
testDetermination( "Oracle", 11, Oracle10gDialect.class, resolver );
testDetermination( "DB2 UDB for AS/400", DB2Dialect.class, resolver );
testDetermination( "DB2 UDB for AS/400", 7, 3, DB2Dialect.class, resolver );
testDetermination( "Oracle", 8, OracleDialect.class, resolver );
testDetermination( "Oracle", 9, OracleDialect.class, resolver );
testDetermination( "Oracle", 10, OracleDialect.class, resolver );
testDetermination( "Oracle", 11, OracleDialect.class, resolver );
}
@Test

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect.resolver;
package org.hibernate.orm.test.dialect.resolver;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

View File

@ -0,0 +1,64 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.dialect.resolver;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry.JavaService;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
/**
* Tests discovery of DialectResolvers via Java's {@link java.util.ServiceLoader}
*/
@BootstrapServiceRegistry(
javaServices = @JavaService(
role = DialectResolver.class,
impl = DiscoveredDialectResolverTests.CustomDialectResolverImpl.class
)
)
@ServiceRegistry(
// force discovery
settings = @Setting( name = AvailableSettings.DIALECT, value = "" )
)
@DomainModel
@SessionFactory
public class DiscoveredDialectResolverTests {
@Test
public void testRegistration(SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
final Dialect dialect = sessionFactory.getJdbcServices().getDialect();
assertThat( dialect, instanceOf( CustomDialect.class ) );
}
public static class CustomDialectResolverImpl implements DialectResolver {
public CustomDialectResolverImpl() {
}
@Override
public Dialect resolveDialect(DialectResolutionInfo info) {
return new CustomDialect();
}
}
public static class CustomDialect extends H2Dialect {
}
}

View File

@ -4,12 +4,12 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect.resolver;
package org.hibernate.orm.test.dialect.resolver;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
/**
* @author Steve Ebersole
* DialectResolutionInfo implementation used in testing
*/
public class TestingDialectResolutionInfo implements DialectResolutionInfo {
private final String databaseName;
@ -58,17 +58,28 @@ public class TestingDialectResolutionInfo implements DialectResolutionInfo {
@Override
public String getDatabaseVersion() {
return databaseMajorVersion + "." + databaseMinorVersion;
if ( databaseMajorVersion == NO_VERSION ) {
if ( databaseMinorVersion == NO_VERSION ) {
return null;
}
return Integer.toString( databaseMinorVersion );
}
else {
if ( databaseMinorVersion == NO_VERSION ) {
return Integer.toString( databaseMajorVersion );
}
return databaseMajorVersion + "." + databaseMinorVersion;
}
}
@Override
public int getDatabaseMajorVersion() {
return databaseMajorVersion;
return databaseMajorVersion == NO_VERSION ? 0 : databaseMajorVersion;
}
@Override
public int getDatabaseMinorVersion() {
return databaseMinorVersion;
return databaseMinorVersion == NO_VERSION ? 0 : databaseMinorVersion;
}
@Override
@ -78,11 +89,11 @@ public class TestingDialectResolutionInfo implements DialectResolutionInfo {
@Override
public int getDriverMajorVersion() {
return driverMajorVersion;
return driverMajorVersion == NO_VERSION ? 0 : driverMajorVersion;
}
@Override
public int getDriverMinorVersion() {
return driverMinorVersion;
return driverMinorVersion == NO_VERSION ? 0 : driverMinorVersion;
}
}

View File

@ -76,16 +76,16 @@ public class DomainModelExtension
throw new RuntimeException( "Unable to determine how to handle given ExtensionContext : " + context.getDisplayName() );
}
final Optional<DomainModel> testDomainAnnotationWrapper = AnnotationSupport.findAnnotation(
final Optional<DomainModel> domainModelAnnotationWrapper = AnnotationSupport.findAnnotation(
context.getElement().get(),
DomainModel.class
);
if ( !testDomainAnnotationWrapper.isPresent() ) {
throw new RuntimeException( "Could not locate @TestDomain annotation : " + context.getDisplayName() );
if ( !domainModelAnnotationWrapper.isPresent() ) {
throw new RuntimeException( "Could not locate @DomainModel annotation : " + context.getDisplayName() );
}
final DomainModel domainModelAnnotation = testDomainAnnotationWrapper.get();
final DomainModel domainModelAnnotation = domainModelAnnotationWrapper.get();
final MetadataSources metadataSources = new MetadataSources( serviceRegistry );