HHH-8561 - hibernate.dialect_resolvers causes failures
This commit is contained in:
parent
4428464d09
commit
3d366a526e
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.internal;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.boot.registry.StandardServiceInitiator;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseInfoDialectResolver;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.service.spi.ServiceException;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
||||
/**
|
||||
* Initiator for the DatabaseInfoDialectResolver service
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DatabaseInfoDialectResolverInitiator implements StandardServiceInitiator<DatabaseInfoDialectResolver> {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final DatabaseInfoDialectResolverInitiator INSTANCE = new DatabaseInfoDialectResolverInitiator();
|
||||
|
||||
@Override
|
||||
public Class<DatabaseInfoDialectResolver> getServiceInitiated() {
|
||||
return DatabaseInfoDialectResolver.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseInfoDialectResolver initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
|
||||
final DatabaseInfoDialectResolverSet resolver = new DatabaseInfoDialectResolverSet();
|
||||
applyCustomReslvers( resolver, configurationValues, registry );
|
||||
resolver.addResolver( StandardDatabaseInfoDialectResolver.INSTANCE );
|
||||
return resolver;
|
||||
}
|
||||
|
||||
private void applyCustomReslvers(
|
||||
DatabaseInfoDialectResolverSet resolver,
|
||||
Map configurationValues,
|
||||
ServiceRegistryImplementor registry) {
|
||||
final String resolverImplNames = (String) configurationValues.get( AvailableSettings.DIALECT_RESOLVERS );
|
||||
|
||||
if ( StringHelper.isNotEmpty( resolverImplNames ) ) {
|
||||
final ClassLoaderService classLoaderService = registry.getService( ClassLoaderService.class );
|
||||
for ( String resolverImplName : StringHelper.split( ", \n\r\f\t", resolverImplNames ) ) {
|
||||
try {
|
||||
resolver.addResolver(
|
||||
(DatabaseInfoDialectResolver) classLoaderService.classForName( resolverImplName ).newInstance()
|
||||
);
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ServiceException( "Unable to instantiate named dialect resolver [" + resolverImplName + "]", e );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseInfoDialectResolver;
|
||||
|
||||
/**
|
||||
* Implements the DatabaseInfoDialectResolver as a chain, allowing multiple delegate DatabaseInfoDialectResolver
|
||||
* implementations to coordinate resolution
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DatabaseInfoDialectResolverSet implements DatabaseInfoDialectResolver {
|
||||
private List<DatabaseInfoDialectResolver> delegateResolvers;
|
||||
|
||||
/**
|
||||
* Constructs a DatabaseInfoDialectResolverSet
|
||||
*/
|
||||
public DatabaseInfoDialectResolverSet() {
|
||||
this( new ArrayList<DatabaseInfoDialectResolver>() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DatabaseInfoDialectResolverSet
|
||||
*
|
||||
* @param delegateResolvers The set of delegate resolvers
|
||||
*/
|
||||
public DatabaseInfoDialectResolverSet(List<DatabaseInfoDialectResolver> delegateResolvers) {
|
||||
this.delegateResolvers = delegateResolvers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DatabaseInfoDialectResolverSet
|
||||
*
|
||||
* @param delegateResolvers The set of delegate resolvers
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public DatabaseInfoDialectResolverSet(DatabaseInfoDialectResolver... delegateResolvers) {
|
||||
this( Arrays.asList( delegateResolvers ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialect resolve(DatabaseInfo databaseInfo) {
|
||||
for ( DatabaseInfoDialectResolver resolver : delegateResolvers ) {
|
||||
final Dialect dialect = resolver.resolve( databaseInfo );
|
||||
if ( dialect != null ) {
|
||||
return dialect;
|
||||
}
|
||||
}
|
||||
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(DatabaseInfoDialectResolver resolver) {
|
||||
delegateResolvers.add( resolver );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public void addResolverAtFirst(DatabaseInfoDialectResolver resolver) {
|
||||
delegateResolvers.add( 0, resolver );
|
||||
}
|
||||
}
|
|
@ -23,9 +23,6 @@
|
|||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -34,37 +31,44 @@ import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
|||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectFactory;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfoSource;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.hibernate.service.spi.InjectService;
|
||||
import org.hibernate.service.spi.ServiceRegistryAwareService;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
||||
/**
|
||||
* Standard implementation of the {@link DialectFactory} service.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DialectFactoryImpl implements DialectFactory {
|
||||
public class DialectFactoryImpl implements DialectFactory, ServiceRegistryAwareService {
|
||||
private StrategySelector strategySelector;
|
||||
|
||||
@InjectService
|
||||
public void setStrategySelector(StrategySelector strategySelector) {
|
||||
this.strategySelector = strategySelector;
|
||||
}
|
||||
|
||||
private DialectResolver dialectResolver;
|
||||
|
||||
@InjectService
|
||||
@Override
|
||||
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||
this.strategySelector = serviceRegistry.getService( StrategySelector.class );
|
||||
this.dialectResolver = serviceRegistry.getService( DialectResolver.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Intended only for use from testing.
|
||||
*
|
||||
* @param dialectResolver The DialectResolver to use
|
||||
*/
|
||||
public void setDialectResolver(DialectResolver dialectResolver) {
|
||||
this.dialectResolver = dialectResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialect buildDialect(Map configValues, Connection connection) throws HibernateException {
|
||||
public Dialect buildDialect(Map configValues, DialectResolutionInfoSource resolutionInfoSource) throws HibernateException {
|
||||
final String dialectName = (String) configValues.get( AvailableSettings.DIALECT );
|
||||
if ( !StringHelper.isEmpty( dialectName ) ) {
|
||||
return constructDialect( dialectName );
|
||||
}
|
||||
else {
|
||||
return determineDialect( connection );
|
||||
return determineDialect( resolutionInfoSource );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,36 +92,29 @@ public class DialectFactoryImpl implements DialectFactory {
|
|||
/**
|
||||
* Determine the appropriate Dialect to use given the connection.
|
||||
*
|
||||
* @param connection The configured connection.
|
||||
* @param resolutionInfoSource Access to DialectResolutionInfo used to resolve the Dialect.
|
||||
*
|
||||
* @return The appropriate dialect instance.
|
||||
*
|
||||
* @throws HibernateException No connection given or no resolver could make
|
||||
* the determination from the given connection.
|
||||
*/
|
||||
private Dialect determineDialect(Connection connection) {
|
||||
if ( connection == null ) {
|
||||
throw new HibernateException( "Connection cannot be null when 'hibernate.dialect' not set" );
|
||||
private Dialect determineDialect(DialectResolutionInfoSource resolutionInfoSource) {
|
||||
if ( resolutionInfoSource == null ) {
|
||||
throw new HibernateException( "Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set" );
|
||||
}
|
||||
|
||||
try {
|
||||
final DatabaseMetaData databaseMetaData = connection.getMetaData();
|
||||
final Dialect dialect = dialectResolver.resolveDialect( databaseMetaData );
|
||||
final DialectResolutionInfo info = resolutionInfoSource.getDialectResolutionInfo();
|
||||
final Dialect dialect = dialectResolver.resolveDialect( info );
|
||||
|
||||
if ( dialect == null ) {
|
||||
throw new HibernateException(
|
||||
"Unable to determine Dialect to use [name=" + databaseMetaData.getDatabaseProductName() +
|
||||
", majorVersion=" + databaseMetaData.getDatabaseMajorVersion() +
|
||||
"]; user must register resolver or explicitly set 'hibernate.dialect'"
|
||||
);
|
||||
}
|
||||
|
||||
return dialect;
|
||||
}
|
||||
catch ( SQLException sqlException ) {
|
||||
if ( dialect == null ) {
|
||||
throw new HibernateException(
|
||||
"Unable to access java.sql.DatabaseMetaData to determine appropriate Dialect to use",
|
||||
sqlException
|
||||
"Unable to determine Dialect to use [name=" + info.getDatabaseName() +
|
||||
", majorVersion=" + info.getDatabaseMajorVersion() +
|
||||
"]; user must register resolver or explicitly set 'hibernate.dialect'"
|
||||
);
|
||||
}
|
||||
|
||||
return dialect;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.boot.registry.StandardServiceInitiator;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseInfoDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.service.spi.ServiceException;
|
||||
|
@ -55,12 +54,10 @@ public class DialectResolverInitiator implements StandardServiceInitiator<Dialec
|
|||
@Override
|
||||
public DialectResolver initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
|
||||
final DialectResolverSet resolver = new DialectResolverSet();
|
||||
|
||||
applyCustomerResolvers( resolver, registry, configurationValues );
|
||||
resolver.addResolver(
|
||||
new StandardDatabaseMetaDataDialectResolver(
|
||||
registry.getService( DatabaseInfoDialectResolver.class )
|
||||
)
|
||||
);
|
||||
resolver.addResolver(StandardDialectResolver.INSTANCE );
|
||||
|
||||
return resolver;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,68 +23,45 @@
|
|||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
/**
|
||||
* A {@link DialectResolver} implementation which coordinates resolution by delegating to sub-resolvers.
|
||||
*
|
||||
* @author Tomoto Shimizu Washio
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
* @deprecated See deprecation on {@link DialectResolver}
|
||||
*/
|
||||
@Deprecated
|
||||
public class DialectResolverSet implements DialectResolver {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
DialectResolverSet.class.getName()
|
||||
);
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DialectResolverSet.class );
|
||||
|
||||
private List<DialectResolver> resolvers;
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
*/
|
||||
public DialectResolverSet() {
|
||||
this( new ArrayList<DialectResolver>() );
|
||||
LOG.debug( "DialectResolverSet is deprecated" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
*
|
||||
* @param resolvers The delegate resolvers
|
||||
*/
|
||||
public DialectResolverSet(List<DialectResolver> resolvers) {
|
||||
this.resolvers = resolvers;
|
||||
LOG.debug( "DialectResolverSet is deprecated" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
*
|
||||
* @param resolvers The delegate resolvers
|
||||
*/
|
||||
public DialectResolverSet(DialectResolver... resolvers) {
|
||||
this( Arrays.asList( resolvers ) );
|
||||
LOG.debug( "DialectResolverSet is deprecated" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialect resolveDialect(DatabaseMetaData metaData) throws JDBCConnectionException {
|
||||
public Dialect resolveDialect(DialectResolutionInfo info) {
|
||||
for ( DialectResolver resolver : resolvers ) {
|
||||
try {
|
||||
final Dialect dialect = resolver.resolveDialect( metaData );
|
||||
final Dialect dialect = resolver.resolveDialect( info );
|
||||
if ( dialect != null ) {
|
||||
return dialect;
|
||||
}
|
||||
|
@ -93,9 +70,10 @@ public class DialectResolverSet implements DialectResolver {
|
|||
throw e;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
LOG.exceptionInSubResolver(e.getMessage());
|
||||
LOG.exceptionInSubResolver( e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.BasicSQLExceptionConverter;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.AbstractDatabaseMetaDataDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseInfoDialectResolver;
|
||||
|
||||
/**
|
||||
* The standard Hibernate Dialect resolver.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardDatabaseMetaDataDialectResolver extends AbstractDatabaseMetaDataDialectResolver {
|
||||
private final DatabaseInfoDialectResolver infoResolver;
|
||||
|
||||
/**
|
||||
* Constructs a StandardDatabaseMetaDataDialectResolver
|
||||
*
|
||||
* @param infoResolver The delegate resolver
|
||||
*/
|
||||
public StandardDatabaseMetaDataDialectResolver(DatabaseInfoDialectResolver infoResolver) {
|
||||
this.infoResolver = infoResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* A DatabaseInfo implementation wrapping a JDBC DatabaseMetaData reference
|
||||
*/
|
||||
public static final class DatabaseInfoImpl implements DatabaseInfoDialectResolver.DatabaseInfo {
|
||||
private final DatabaseMetaData databaseMetaData;
|
||||
|
||||
protected DatabaseInfoImpl(DatabaseMetaData databaseMetaData) {
|
||||
this.databaseMetaData = databaseMetaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseName() {
|
||||
try {
|
||||
return databaseMetaData.getDatabaseProductName();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMajorVersion() {
|
||||
try {
|
||||
return databaseMetaData.getDatabaseMajorVersion();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMinorVersion() {
|
||||
try {
|
||||
return databaseMetaData.getDatabaseMinorVersion();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
|
||||
if ( infoResolver == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return infoResolver.resolve( new DatabaseInfoImpl( metaData ) );
|
||||
}
|
||||
}
|
|
@ -52,29 +52,27 @@ import org.hibernate.dialect.SQLServer2012Dialect;
|
|||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.dialect.SybaseASE15Dialect;
|
||||
import org.hibernate.dialect.SybaseAnywhereDialect;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseInfoDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* The standard DatabaseInfoDialectResolver implementation
|
||||
* The standard DialectResolver implementation
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardDatabaseInfoDialectResolver implements DatabaseInfoDialectResolver {
|
||||
public class StandardDialectResolver implements DialectResolver {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( StandardDialectResolver.class );
|
||||
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final StandardDatabaseInfoDialectResolver INSTANCE = new StandardDatabaseInfoDialectResolver();
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
StandardDatabaseInfoDialectResolver.class.getName()
|
||||
);
|
||||
public static final StandardDialectResolver INSTANCE = new StandardDialectResolver();
|
||||
|
||||
@Override
|
||||
public Dialect resolve(DatabaseInfo databaseInfo) {
|
||||
final String databaseName = databaseInfo.getDatabaseName();
|
||||
public Dialect resolveDialect(DialectResolutionInfo info) {
|
||||
final String databaseName = info.getDatabaseName();
|
||||
|
||||
if ( "CUBRID".equalsIgnoreCase( databaseName ) ) {
|
||||
return new CUBRIDDialect();
|
||||
|
@ -89,7 +87,7 @@ public class StandardDatabaseInfoDialectResolver implements DatabaseInfoDialectR
|
|||
}
|
||||
|
||||
if ( "MySQL".equals( databaseName ) ) {
|
||||
final int majorVersion = databaseInfo.getDatabaseMajorVersion();
|
||||
final int majorVersion = info.getDatabaseMajorVersion();
|
||||
|
||||
if (majorVersion >= 5 ) {
|
||||
return new MySQL5Dialect();
|
||||
|
@ -99,8 +97,8 @@ public class StandardDatabaseInfoDialectResolver implements DatabaseInfoDialectR
|
|||
}
|
||||
|
||||
if ( "PostgreSQL".equals( databaseName ) ) {
|
||||
final int majorVersion = databaseInfo.getDatabaseMajorVersion();
|
||||
final int minorVersion = databaseInfo.getDatabaseMinorVersion();
|
||||
final int majorVersion = info.getDatabaseMajorVersion();
|
||||
final int minorVersion = info.getDatabaseMinorVersion();
|
||||
|
||||
if ( majorVersion == 9 ) {
|
||||
return new PostgreSQL9Dialect();
|
||||
|
@ -118,8 +116,8 @@ public class StandardDatabaseInfoDialectResolver implements DatabaseInfoDialectR
|
|||
}
|
||||
|
||||
if ( "Apache Derby".equals( databaseName ) ) {
|
||||
final int majorVersion = databaseInfo.getDatabaseMajorVersion();
|
||||
final int minorVersion = databaseInfo.getDatabaseMinorVersion();
|
||||
final int majorVersion = info.getDatabaseMajorVersion();
|
||||
final int minorVersion = info.getDatabaseMinorVersion();
|
||||
|
||||
if ( majorVersion > 10 || ( majorVersion == 10 && minorVersion >= 7 ) ) {
|
||||
return new DerbyTenSevenDialect();
|
||||
|
@ -136,8 +134,8 @@ public class StandardDatabaseInfoDialectResolver implements DatabaseInfoDialectR
|
|||
}
|
||||
|
||||
if ( "ingres".equalsIgnoreCase( databaseName ) ) {
|
||||
final int majorVersion = databaseInfo.getDatabaseMajorVersion();
|
||||
final int minorVersion = databaseInfo.getDatabaseMinorVersion();
|
||||
final int majorVersion = info.getDatabaseMajorVersion();
|
||||
final int minorVersion = info.getDatabaseMinorVersion();
|
||||
|
||||
switch ( majorVersion ) {
|
||||
case 9:
|
||||
|
@ -154,7 +152,7 @@ public class StandardDatabaseInfoDialectResolver implements DatabaseInfoDialectR
|
|||
}
|
||||
|
||||
if ( databaseName.startsWith( "Microsoft SQL Server" ) ) {
|
||||
final int majorVersion = databaseInfo.getDatabaseMajorVersion();
|
||||
final int majorVersion = info.getDatabaseMajorVersion();
|
||||
|
||||
switch ( majorVersion ) {
|
||||
case 8:
|
||||
|
@ -192,7 +190,7 @@ public class StandardDatabaseInfoDialectResolver implements DatabaseInfoDialectR
|
|||
}
|
||||
|
||||
if ( "Oracle".equals( databaseName ) ) {
|
||||
final int majorVersion = databaseInfo.getDatabaseMajorVersion();
|
||||
final int majorVersion = info.getDatabaseMajorVersion();
|
||||
|
||||
switch ( majorVersion ) {
|
||||
case 11:
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.spi;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
/**
|
||||
* A templated resolver impl which delegates to the {@link #resolveDialectInternal} method
|
||||
* and handles any thrown {@link SQLException SQL errors}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractDatabaseMetaDataDialectResolver implements DialectResolver {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
AbstractDatabaseMetaDataDialectResolver.class.getName()
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p/>
|
||||
* Here we template the resolution, delegating to {@link #resolveDialectInternal} and handling
|
||||
* {@link java.sql.SQLException}s properly.
|
||||
*/
|
||||
@Override
|
||||
public final Dialect resolveDialect(DatabaseMetaData metaData) {
|
||||
try {
|
||||
return resolveDialectInternal( metaData );
|
||||
}
|
||||
catch ( SQLException sqlException ) {
|
||||
final JDBCException jdbcException = BasicSQLExceptionConverter.INSTANCE.convert( sqlException );
|
||||
if (jdbcException instanceof JDBCConnectionException) {
|
||||
throw jdbcException;
|
||||
}
|
||||
|
||||
LOG.warnf( "%s : %s", BasicSQLExceptionConverter.MSG, sqlException.getMessage() );
|
||||
return null;
|
||||
}
|
||||
catch ( Throwable t ) {
|
||||
LOG.unableToExecuteResolver( this, t.getMessage() );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the actual resolution without caring about handling {@link SQLException}s.
|
||||
*
|
||||
* @param metaData The database metadata
|
||||
* @return The resolved dialect, or null if we could not resolve.
|
||||
* @throws SQLException Indicates problems accessing the metadata.
|
||||
*/
|
||||
protected abstract Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException;
|
||||
}
|
|
@ -21,64 +21,69 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
package org.hibernate.engine.jdbc.dialect.spi;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.AbstractDatabaseMetaDataDialectResolver;
|
||||
|
||||
import static org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo.NO_VERSION;
|
||||
|
||||
/**
|
||||
* Intended as support for custom resolvers.
|
||||
* Intended as support for custom resolvers which match a single db name (with optional version info).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
* @deprecated Purpose has shifted to new {@link org.hibernate.engine.jdbc.dialect.spi.DatabaseInfoDialectResolver}
|
||||
* contract. See <a href="https://hibernate.onjira.com/browse/HHH-7965">HHH-7965</a> for details.
|
||||
*/
|
||||
@Deprecated
|
||||
public class BasicDialectResolver extends AbstractDatabaseMetaDataDialectResolver {
|
||||
/**
|
||||
* Constant indicating no version info was given
|
||||
*/
|
||||
public static final int VERSION_INSENSITIVE_VERSION = -9999;
|
||||
public class BasicDialectResolver implements DialectResolver {
|
||||
private final String nameToMatch;
|
||||
private final int majorVersionToMatch;
|
||||
private final int minorVersionToMatch;
|
||||
|
||||
private final String matchingName;
|
||||
private final int matchingVersion;
|
||||
private final Class dialectClass;
|
||||
|
||||
/**
|
||||
* Constructs a BasicDialectResolver
|
||||
*
|
||||
* @param matchingName The name of the driver to match on
|
||||
* @param nameToMatch The name of the driver to match on
|
||||
* @param dialectClass The Dialect class to use on match
|
||||
*/
|
||||
public BasicDialectResolver(String matchingName, Class dialectClass) {
|
||||
this( matchingName, VERSION_INSENSITIVE_VERSION, dialectClass );
|
||||
public BasicDialectResolver(String nameToMatch, Class dialectClass) {
|
||||
this( nameToMatch, NO_VERSION, dialectClass );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a BasicDialectResolver
|
||||
*
|
||||
* @param matchingName The name of the driver to match on
|
||||
* @param matchingVersion The version of the driver to match on
|
||||
* @param nameToMatch The name of the driver to match on
|
||||
* @param majorVersionToMatch The version of the driver to match on
|
||||
* @param dialectClass The Dialect class to use on match
|
||||
*/
|
||||
public BasicDialectResolver(String matchingName, int matchingVersion, Class dialectClass) {
|
||||
this.matchingName = matchingName;
|
||||
this.matchingVersion = matchingVersion;
|
||||
public BasicDialectResolver(String nameToMatch, int majorVersionToMatch, Class dialectClass) {
|
||||
this( nameToMatch, majorVersionToMatch, NO_VERSION, dialectClass );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a BasicDialectResolver
|
||||
*
|
||||
* @param nameToMatch The name of the driver to match on
|
||||
* @param majorVersionToMatch The version of the driver to match on
|
||||
* @param dialectClass The Dialect class to use on match
|
||||
*/
|
||||
public BasicDialectResolver(String nameToMatch, int majorVersionToMatch, int minorVersionToMatch, Class dialectClass) {
|
||||
this.nameToMatch = nameToMatch;
|
||||
this.majorVersionToMatch = majorVersionToMatch;
|
||||
this.minorVersionToMatch = minorVersionToMatch;
|
||||
this.dialectClass = dialectClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
|
||||
final String databaseName = metaData.getDatabaseProductName();
|
||||
final int databaseMajorVersion = metaData.getDatabaseMajorVersion();
|
||||
public final Dialect resolveDialect(DialectResolutionInfo info) {
|
||||
final String databaseName = info.getDatabaseName();
|
||||
final int databaseMajorVersion = info.getDatabaseMajorVersion();
|
||||
final int databaseMinorVersion = info.getDatabaseMinorVersion();
|
||||
|
||||
if ( matchingName.equalsIgnoreCase( databaseName )
|
||||
&& ( matchingVersion == VERSION_INSENSITIVE_VERSION || matchingVersion == databaseMajorVersion ) ) {
|
||||
if ( nameToMatch.equalsIgnoreCase( databaseName )
|
||||
&& ( majorVersionToMatch == NO_VERSION || majorVersionToMatch == databaseMajorVersion )
|
||||
&& ( minorVersionToMatch == NO_VERSION || majorVersionToMatch == databaseMinorVersion ) ) {
|
||||
try {
|
||||
return (Dialect) dialectClass.newInstance();
|
||||
}
|
|
@ -29,6 +29,7 @@ import org.jboss.logging.Logger;
|
|||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.exception.internal.SQLStateConverter;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
/**
|
||||
|
@ -39,10 +40,7 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicSQLExceptionConverter {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
BasicSQLExceptionConverter.class.getName()
|
||||
);
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( BasicSQLExceptionConverter.class );
|
||||
|
||||
/**
|
||||
* Singleton access
|
||||
|
@ -67,9 +65,6 @@ public class BasicSQLExceptionConverter {
|
|||
}
|
||||
|
||||
private static class ConstraintNameExtracter implements ViolatedConstraintNameExtracter {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
return "???";
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.spi;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.service.Service;
|
||||
|
||||
/**
|
||||
* A contract for resolving database name, major version and minor version to Dialect
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface DatabaseInfoDialectResolver extends Service {
|
||||
/**
|
||||
* Determine the {@link Dialect} to use based on the given information. Implementations are
|
||||
* expected to return the {@link Dialect} instance to use, or {@code null} if the they did not locate a match.
|
||||
*
|
||||
* @param databaseInfo Access to the needed database information
|
||||
*
|
||||
* @return The dialect to use, or null.
|
||||
*/
|
||||
public Dialect resolve(DatabaseInfo databaseInfo);
|
||||
|
||||
/**
|
||||
* Essentially a "parameter object" for {@link DatabaseInfoDialectResolver#resolve}
|
||||
*/
|
||||
public static interface DatabaseInfo {
|
||||
/**
|
||||
* Constant used to indicate that no version is defined
|
||||
*/
|
||||
public static final int NO_VERSION = -9999;
|
||||
|
||||
/**
|
||||
* Obtain access to the database name, as returned from {@link java.sql.DatabaseMetaData#getDatabaseProductName()}
|
||||
* for the target database
|
||||
*
|
||||
* @return The database name
|
||||
*/
|
||||
public String getDatabaseName();
|
||||
|
||||
/**
|
||||
* Obtain access to the database major version, as returned from
|
||||
* {@link java.sql.DatabaseMetaData#getDatabaseMajorVersion()} for the target database; {@value #NO_VERSION}
|
||||
* indicates no version information was supplied
|
||||
*
|
||||
* @return The major version
|
||||
*
|
||||
* @see #NO_VERSION
|
||||
*/
|
||||
public int getDatabaseMajorVersion();
|
||||
|
||||
/**
|
||||
* Obtain access to the database minor version, as returned from
|
||||
* {@link java.sql.DatabaseMetaData#getDatabaseMinorVersion()} for the target database; {@value #NO_VERSION}
|
||||
* indicates no version information was supplied
|
||||
*
|
||||
* @return The minor version
|
||||
*
|
||||
* @see #NO_VERSION
|
||||
*/
|
||||
public int getDatabaseMinorVersion();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.spi;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.dialect.spi.BasicSQLExceptionConverter;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
|
||||
/**
|
||||
* An implementation of DialectResolutionInfo that delegates calls to a wrapped {@link DatabaseMetaData}.
|
||||
* <p/>
|
||||
* All {@link SQLException}s resulting from calls on the DatabaseMetaData are converted to the Hibernate
|
||||
* {@link org.hibernate.JDBCException} hierarchy.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DatabaseMetaDataDialectResolutionInfoAdapter implements DialectResolutionInfo {
|
||||
private final DatabaseMetaData databaseMetaData;
|
||||
|
||||
public DatabaseMetaDataDialectResolutionInfoAdapter(DatabaseMetaData databaseMetaData) {
|
||||
this.databaseMetaData = databaseMetaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseName() {
|
||||
try {
|
||||
return databaseMetaData.getDatabaseProductName();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMajorVersion() {
|
||||
try {
|
||||
return interpretVersion( databaseMetaData.getDatabaseMajorVersion() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
|
||||
}
|
||||
}
|
||||
|
||||
private static int interpretVersion(int result) {
|
||||
return result < 0 ? NO_VERSION : result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMinorVersion() {
|
||||
try {
|
||||
return interpretVersion( databaseMetaData.getDatabaseMinorVersion() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverName() {
|
||||
try {
|
||||
return databaseMetaData.getDriverName();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw BasicSQLExceptionConverter.INSTANCE.convert( e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMajorVersion() {
|
||||
return interpretVersion( databaseMetaData.getDriverMajorVersion() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMinorVersion() {
|
||||
return interpretVersion( databaseMetaData.getDriverMinorVersion() );
|
||||
}
|
||||
}
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.spi;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -46,11 +45,12 @@ public interface DialectFactory extends Service {
|
|||
* the determination from the given connection.
|
||||
*
|
||||
* @param configValues The configuration properties.
|
||||
* @param connection The configured connection.
|
||||
* @param resolutionInfoSource Access to DialectResolutionInfo used to resolve the Dialect to use if not
|
||||
* explicitly named
|
||||
*
|
||||
* @return The appropriate dialect instance.
|
||||
*
|
||||
* @throws HibernateException No dialect specified and no resolver could make the determination.
|
||||
*/
|
||||
public Dialect buildDialect(Map configValues, Connection connection) throws HibernateException;
|
||||
public Dialect buildDialect(Map configValues, DialectResolutionInfoSource resolutionInfoSource) throws HibernateException;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.spi;
|
||||
|
||||
/**
|
||||
* Exposes information about the database and JDBC driver that can be used in resolving the appropriate Dialect
|
||||
* to use.
|
||||
* <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;
|
||||
|
||||
/**
|
||||
* Obtain access to the database name, as returned from {@link java.sql.DatabaseMetaData#getDatabaseProductName()}
|
||||
* for the target database
|
||||
*
|
||||
* @return The database name
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getDatabaseProductName()
|
||||
*/
|
||||
public String getDatabaseName();
|
||||
|
||||
/**
|
||||
* Obtain access to the database major version, as returned from
|
||||
* {@link java.sql.DatabaseMetaData#getDatabaseMajorVersion()} for the target database.
|
||||
*
|
||||
* @return The database major version, or {@value #NO_VERSION} to indicate "no version information"
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getDatabaseMajorVersion()
|
||||
*/
|
||||
public int getDatabaseMajorVersion();
|
||||
|
||||
/**
|
||||
* Obtain access to the database minor version, as returned from
|
||||
* {@link java.sql.DatabaseMetaData#getDatabaseMinorVersion()} for the target database.
|
||||
*
|
||||
* @return The database minor version, or {@value #NO_VERSION} to indicate "no version information"
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getDatabaseMinorVersion()
|
||||
*/
|
||||
public int getDatabaseMinorVersion();
|
||||
|
||||
/**
|
||||
* Obtain access to the name of the JDBC driver, as returned from {@link java.sql.DatabaseMetaData#getDriverName()}
|
||||
* for the target database
|
||||
*
|
||||
* @return The JDBC driver name
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getDriverName()
|
||||
*/
|
||||
public String getDriverName();
|
||||
|
||||
/**
|
||||
* Obtain access to the major version of the JDBC driver, as returned from
|
||||
* {@link java.sql.DatabaseMetaData#getDriverMajorVersion()} ()} for the target database.
|
||||
*
|
||||
* @return The JDBC driver major version, or {@value #NO_VERSION} to indicate "no version information"
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getDriverMajorVersion()
|
||||
*/
|
||||
public int getDriverMajorVersion();
|
||||
|
||||
/**
|
||||
* Obtain access to the minor version of the JDBC driver, as returned from
|
||||
* {@link java.sql.DatabaseMetaData#getDriverMinorVersion()} for the target database.
|
||||
*
|
||||
* @return The JDBC driver minor version, or {@value #NO_VERSION} to indicate "no version information"
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getDriverMinorVersion()
|
||||
*/
|
||||
public int getDriverMinorVersion();
|
||||
|
||||
|
||||
}
|
|
@ -23,30 +23,16 @@
|
|||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.spi;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
import org.hibernate.service.Service;
|
||||
|
||||
/**
|
||||
* Contract for determining the {@link Dialect} to use based on a JDBC {@link java.sql.Connection}.
|
||||
* Contract for the source of DialectResolutionInfo.
|
||||
*
|
||||
* @author Tomoto Shimizu Washio
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface DatabaseMetaDataDialectResolver extends Service {
|
||||
public interface DialectResolutionInfoSource {
|
||||
/**
|
||||
* Determine the {@link org.hibernate.dialect.Dialect} to use based on the given JDBC {@link java.sql.DatabaseMetaData}. Implementations are
|
||||
* expected to return the {@link org.hibernate.dialect.Dialect} instance to use, or null if the {@link java.sql.DatabaseMetaData} does not match
|
||||
* the criteria handled by this impl.
|
||||
* Get the DialectResolutionInfo
|
||||
*
|
||||
* @param metaData The JDBC metadata.
|
||||
*
|
||||
* @return The dialect to use, or null.
|
||||
*
|
||||
* @throws org.hibernate.exception.JDBCConnectionException Indicates a 'non transient connection problem', which indicates that
|
||||
* we should stop resolution attempts.
|
||||
* @return The DialectResolutionInfo
|
||||
*/
|
||||
public Dialect resolveDialect(DatabaseMetaData metaData) throws JDBCConnectionException;
|
||||
public DialectResolutionInfo getDialectResolutionInfo();
|
||||
}
|
|
@ -23,15 +23,23 @@
|
|||
*/
|
||||
package org.hibernate.engine.jdbc.dialect.spi;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.service.Service;
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
* Contract for determining the {@link Dialect} to use based on information about the database / driver.
|
||||
*
|
||||
* @deprecated Deprecated in favor of {@link DatabaseMetaDataDialectResolver} to account for resolving by name versus
|
||||
* by DatabaseMetaData
|
||||
*
|
||||
* @see DatabaseMetaDataDialectResolver
|
||||
* @see DatabaseInfoDialectResolver
|
||||
* @author Tomoto Shimizu Washio
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Deprecated
|
||||
public interface DialectResolver extends DatabaseMetaDataDialectResolver {
|
||||
public interface DialectResolver extends Service {
|
||||
/**
|
||||
* Determine the {@link Dialect} to use based on the given information. Implementations are expected to return
|
||||
* the {@link Dialect} instance to use, or {@code null} if the they did not locate a match.
|
||||
*
|
||||
* @param info Access to the information about the database/driver needed to perform the resolution
|
||||
*
|
||||
* @return The dialect to use, or null.
|
||||
*/
|
||||
public Dialect resolveDialect(DialectResolutionInfo info);
|
||||
}
|
||||
|
|
|
@ -36,11 +36,16 @@ import java.util.Set;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.BasicSQLExceptionConverter;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseMetaDataDialectResolutionInfoAdapter;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfoSource;
|
||||
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
|
@ -162,7 +167,23 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
|
|||
lobLocatorUpdateCopy = meta.locatorsUpdateCopy();
|
||||
typeInfoSet.addAll( TypeInfo.extractTypeInfo( meta ) );
|
||||
|
||||
dialect = dialectFactory.buildDialect( configValues, connection );
|
||||
dialect = dialectFactory.buildDialect(
|
||||
configValues,
|
||||
new DialectResolutionInfoSource() {
|
||||
@Override
|
||||
public DialectResolutionInfo getDialectResolutionInfo() {
|
||||
try {
|
||||
return new DatabaseMetaDataDialectResolutionInfoAdapter( connection.getMetaData() );
|
||||
}
|
||||
catch ( SQLException sqlException ) {
|
||||
throw new HibernateException(
|
||||
"Unable to access java.sql.DatabaseMetaData to determine appropriate Dialect to use",
|
||||
sqlException
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
catalogName = connection.getCatalog();
|
||||
final SchemaNameResolver schemaNameResolver = determineExplicitSchemaNameResolver( configValues );
|
||||
|
|
|
@ -29,24 +29,23 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.boot.registry.StandardServiceInitiator;
|
||||
import org.hibernate.cache.internal.RegionFactoryInitiator;
|
||||
import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.DatabaseInfoDialectResolverInitiator;
|
||||
import org.hibernate.engine.jdbc.internal.JdbcServicesInitiator;
|
||||
import org.hibernate.engine.transaction.internal.TransactionFactoryInitiator;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformResolverInitiator;
|
||||
import org.hibernate.id.factory.internal.MutableIdentifierGeneratorFactoryInitiator;
|
||||
import org.hibernate.persister.internal.PersisterClassResolverInitiator;
|
||||
import org.hibernate.persister.internal.PersisterFactoryInitiator;
|
||||
import org.hibernate.engine.config.internal.ConfigurationServiceInitiator;
|
||||
import org.hibernate.service.internal.SessionFactoryServiceRegistryFactoryInitiator;
|
||||
import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator;
|
||||
import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator;
|
||||
import org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator;
|
||||
import org.hibernate.engine.jdbc.cursor.internal.RefCursorSupportInitiator;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.DialectFactoryInitiator;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.DialectResolverInitiator;
|
||||
import org.hibernate.jmx.internal.JmxServiceInitiator;
|
||||
import org.hibernate.engine.jdbc.internal.JdbcServicesInitiator;
|
||||
import org.hibernate.engine.jndi.internal.JndiServiceInitiator;
|
||||
import org.hibernate.engine.transaction.internal.TransactionFactoryInitiator;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformResolverInitiator;
|
||||
import org.hibernate.id.factory.internal.MutableIdentifierGeneratorFactoryInitiator;
|
||||
import org.hibernate.jmx.internal.JmxServiceInitiator;
|
||||
import org.hibernate.persister.internal.PersisterClassResolverInitiator;
|
||||
import org.hibernate.persister.internal.PersisterFactoryInitiator;
|
||||
import org.hibernate.service.internal.SessionFactoryServiceRegistryFactoryInitiator;
|
||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractorInitiator;
|
||||
|
||||
/**
|
||||
|
@ -71,7 +70,6 @@ public class StandardServiceInitiators {
|
|||
|
||||
serviceInitiators.add( ConnectionProviderInitiator.INSTANCE );
|
||||
serviceInitiators.add( MultiTenantConnectionProviderInitiator.INSTANCE );
|
||||
serviceInitiators.add( DatabaseInfoDialectResolverInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectResolverInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectFactoryInitiator.INSTANCE );
|
||||
serviceInitiators.add( BatchBuilderInitiator.INSTANCE );
|
||||
|
|
|
@ -22,12 +22,10 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.BasicDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.AbstractDatabaseMetaDataDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.BasicDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -46,10 +44,11 @@ public class TestingDialects {
|
|||
public static class MySpecialDB2Dialect extends Dialect {
|
||||
}
|
||||
|
||||
public static class MyDialectResolver1 extends AbstractDatabaseMetaDataDialectResolver {
|
||||
protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
|
||||
String databaseName = metaData.getDatabaseProductName();
|
||||
int databaseMajorVersion = metaData.getDatabaseMajorVersion();
|
||||
public static class MyDialectResolver1 implements DialectResolver {
|
||||
@Override
|
||||
public Dialect resolveDialect(DialectResolutionInfo info) {
|
||||
String databaseName = info.getDatabaseName();
|
||||
int databaseMajorVersion = info.getDatabaseMajorVersion();
|
||||
if ( "MyDatabase1".equals( databaseName ) ) {
|
||||
return new MyDialect1();
|
||||
}
|
||||
|
@ -71,31 +70,6 @@ public class TestingDialects {
|
|||
}
|
||||
}
|
||||
|
||||
public static class ErrorDialectResolver1 extends AbstractDatabaseMetaDataDialectResolver {
|
||||
public Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
|
||||
String databaseName = metaData.getDatabaseProductName();
|
||||
if ( databaseName.equals( "ConnectionErrorDatabase1" ) ) {
|
||||
throw new SQLException( "Simulated connection error", "08001" );
|
||||
}
|
||||
else {
|
||||
throw new SQLException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ErrorDialectResolver2 extends AbstractDatabaseMetaDataDialectResolver {
|
||||
public Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
|
||||
String databaseName = metaData.getDatabaseProductName();
|
||||
if ( databaseName.equals( "ErrorDatabase1" ) ) {
|
||||
throw new SQLException();
|
||||
}
|
||||
if ( databaseName.equals( "ErrorDatabase2" ) ) {
|
||||
throw new HibernateException( "This is a trap!" );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyOverridingDialectResolver1 extends BasicDialectResolver {
|
||||
public MyOverridingDialectResolver1() {
|
||||
super( "DB2/MySpecialPlatform", MySpecialDB2Dialect.class );
|
||||
|
|
|
@ -23,10 +23,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect.resolver;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -34,8 +30,10 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
|
||||
import org.hibernate.boot.registry.selector.internal.StrategySelectorBuilder;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelectionException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.DB2400Dialect;
|
||||
|
@ -44,6 +42,7 @@ import org.hibernate.dialect.DerbyDialect;
|
|||
import org.hibernate.dialect.DerbyTenFiveDialect;
|
||||
import org.hibernate.dialect.DerbyTenSevenDialect;
|
||||
import org.hibernate.dialect.DerbyTenSixDialect;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.InformixDialect;
|
||||
|
@ -64,28 +63,35 @@ import org.hibernate.dialect.SybaseAnywhereDialect;
|
|||
import org.hibernate.dialect.TestingDialects;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.StandardDatabaseInfoDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.StandardDatabaseMetaDataDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.StandardDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfoSource;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DialectFactoryTest extends BaseUnitTestCase {
|
||||
private StandardServiceRegistry registry;
|
||||
private DialectFactoryImpl dialectFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final BootstrapServiceRegistry bootReg = new BootstrapServiceRegistryBuilder().with( DialectFactoryTest.class.getClassLoader() ).build();
|
||||
registry = new StandardServiceRegistryBuilder( bootReg ).build();
|
||||
|
||||
dialectFactory = new DialectFactoryImpl();
|
||||
dialectFactory.setStrategySelector(
|
||||
new StrategySelectorBuilder().buildSelector( new ClassLoaderServiceImpl( getClass().getClassLoader() ) )
|
||||
);
|
||||
dialectFactory.setDialectResolver(
|
||||
new StandardDatabaseMetaDataDialectResolver( StandardDatabaseInfoDialectResolver.INSTANCE )
|
||||
);
|
||||
dialectFactory.injectServices( (ServiceRegistryImplementor) registry );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -143,7 +149,7 @@ public class DialectFactoryTest extends BaseUnitTestCase {
|
|||
|
||||
@Test
|
||||
public void testPreregisteredDialects() {
|
||||
DialectResolver resolver = new StandardDatabaseMetaDataDialectResolver( StandardDatabaseInfoDialectResolver.INSTANCE );
|
||||
DialectResolver resolver = StandardDialectResolver.INSTANCE;
|
||||
testDetermination( "HSQL Database Engine", HSQLDialect.class, resolver );
|
||||
testDetermination( "H2", H2Dialect.class, resolver );
|
||||
testDetermination( "MySQL", MySQLDialect.class, resolver );
|
||||
|
@ -184,8 +190,6 @@ public class DialectFactoryTest extends BaseUnitTestCase {
|
|||
DialectResolverSet resolvers = new DialectResolverSet();
|
||||
resolvers.addResolver( new TestingDialects.MyDialectResolver1() );
|
||||
resolvers.addResolver( new TestingDialects.MyDialectResolver2() );
|
||||
resolvers.addResolver( new TestingDialects.ErrorDialectResolver1() );
|
||||
resolvers.addResolver( new TestingDialects.ErrorDialectResolver2() );
|
||||
resolvers.addResolver( new TestingDialects.MyOverridingDialectResolver1() );
|
||||
//DialectFactory.registerDialectResolver( "org.hibernate.dialect.NoSuchDialectResolver" );
|
||||
//DialectFactory.registerDialectResolver( "java.lang.Object" );
|
||||
|
@ -217,7 +221,15 @@ public class DialectFactoryTest extends BaseUnitTestCase {
|
|||
public void testDialectNotFound() {
|
||||
Map properties = Collections.EMPTY_MAP;
|
||||
try {
|
||||
dialectFactory.buildDialect( properties, Mocks.createConnection( "NoSuchDatabase", 666 ) );
|
||||
dialectFactory.buildDialect(
|
||||
properties,
|
||||
new DialectResolutionInfoSource() {
|
||||
@Override
|
||||
public DialectResolutionInfo getDialectResolutionInfo() {
|
||||
return TestingDialectResolutionInfo.forDatabaseInfo( "NoSuchDatabase", 666 );
|
||||
}
|
||||
}
|
||||
);
|
||||
fail();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
|
@ -225,18 +237,30 @@ public class DialectFactoryTest extends BaseUnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
private void testDetermination(String databaseName, Class clazz, DialectResolver resolver) {
|
||||
testDetermination( databaseName, -9999, clazz, resolver );
|
||||
private void testDetermination(String databaseName, Class expected, DialectResolver resolver) {
|
||||
testDetermination( databaseName, -9999, expected, resolver );
|
||||
}
|
||||
|
||||
private void testDetermination(String databaseName, int databaseMajorVersion, Class clazz, DialectResolver resolver) {
|
||||
testDetermination( databaseName, databaseMajorVersion, -9999, clazz, resolver );
|
||||
private void testDetermination(String databaseName, int databaseMajorVersion, Class expected, DialectResolver resolver) {
|
||||
testDetermination( databaseName, databaseMajorVersion, -9999, expected, resolver );
|
||||
}
|
||||
|
||||
private void testDetermination(String databaseName, int majorVersion, int minorVersion, Class clazz, DialectResolver resolver) {
|
||||
private void testDetermination(
|
||||
final String databaseName,
|
||||
final int majorVersion,
|
||||
final int minorVersion,
|
||||
Class expected,
|
||||
DialectResolver resolver) {
|
||||
dialectFactory.setDialectResolver( resolver );
|
||||
Properties properties = new Properties();
|
||||
Connection conn = Mocks.createConnection( databaseName, majorVersion, minorVersion );
|
||||
assertEquals( clazz, dialectFactory.buildDialect( properties, conn ).getClass() );
|
||||
Dialect resolved = dialectFactory.buildDialect(
|
||||
new Properties(),
|
||||
new DialectResolutionInfoSource() {
|
||||
@Override
|
||||
public DialectResolutionInfo getDialectResolutionInfo() {
|
||||
return TestingDialectResolutionInfo.forDatabaseInfo( databaseName, majorVersion, minorVersion );
|
||||
}
|
||||
}
|
||||
);
|
||||
assertEquals( expected, resolved.getClass() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,17 +22,18 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.resolver;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.TestingDialects;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.BasicDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.Mocks;
|
||||
import org.hibernate.dialect.TestingDialects;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.BasicDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -63,23 +64,12 @@ public class DialectResolverTest extends BaseUnitTestCase {
|
|||
public void testErrorAndOrder() throws Exception {
|
||||
DialectResolverSet resolvers = new DialectResolverSet();
|
||||
resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver1() );
|
||||
resolvers.addResolver( new TestingDialects.ErrorDialectResolver1() );
|
||||
resolvers.addResolverAtFirst( new TestingDialects.ErrorDialectResolver1() );
|
||||
resolvers.addResolver( new TestingDialects.MyDialectResolver2() );
|
||||
|
||||
// Non-connection errors are suppressed.
|
||||
testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
|
||||
testDetermination( resolvers, "MyTrickyDatabase1", 1, TestingDialects.MyDialect1.class );
|
||||
testDetermination( resolvers, "NoSuchDatabase", 1, null );
|
||||
|
||||
// Connection errors are reported
|
||||
try {
|
||||
testDetermination( resolvers, "ConnectionErrorDatabase1", 1, null );
|
||||
fail();
|
||||
}
|
||||
catch ( JDBCConnectionException e ) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -105,7 +95,7 @@ public class DialectResolverTest extends BaseUnitTestCase {
|
|||
String databaseName,
|
||||
int version,
|
||||
Class dialectClass) throws SQLException {
|
||||
Dialect dialect = resolver.resolveDialect( Mocks.createConnection( databaseName, version ).getMetaData() );
|
||||
Dialect dialect = resolver.resolveDialect( TestingDialectResolutionInfo.forDatabaseInfo( databaseName, version ) );
|
||||
if ( dialectClass == null ) {
|
||||
assertEquals( null, dialect );
|
||||
}
|
||||
|
@ -113,4 +103,5 @@ public class DialectResolverTest extends BaseUnitTestCase {
|
|||
assertEquals( dialectClass, dialect.getClass() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.resolver;
|
||||
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TestingDialectResolutionInfo implements DialectResolutionInfo {
|
||||
private final String databaseName;
|
||||
private final int databaseMajorVersion;
|
||||
private final int databaseMinorVersion;
|
||||
|
||||
private final String driverName;
|
||||
private final int driverMajorVersion;
|
||||
private final int driverMinorVersion;
|
||||
|
||||
TestingDialectResolutionInfo(
|
||||
String databaseName,
|
||||
int databaseMajorVersion,
|
||||
int databaseMinorVersion,
|
||||
String driverName,
|
||||
int driverMajorVersion,
|
||||
int driverMinorVersion) {
|
||||
this.databaseName = databaseName;
|
||||
this.databaseMajorVersion = databaseMajorVersion;
|
||||
this.databaseMinorVersion = databaseMinorVersion;
|
||||
this.driverName = driverName;
|
||||
this.driverMajorVersion = driverMajorVersion;
|
||||
this.driverMinorVersion = driverMinorVersion;
|
||||
}
|
||||
|
||||
public static TestingDialectResolutionInfo forDatabaseInfo(String name) {
|
||||
return forDatabaseInfo( name, NO_VERSION );
|
||||
}
|
||||
|
||||
public static TestingDialectResolutionInfo forDatabaseInfo(String name, int majorVersion) {
|
||||
return forDatabaseInfo( name, majorVersion, NO_VERSION );
|
||||
}
|
||||
|
||||
public static TestingDialectResolutionInfo forDatabaseInfo(String name, int majorVersion, int minorVersion) {
|
||||
return new TestingDialectResolutionInfo( name, majorVersion, minorVersion, null, NO_VERSION, NO_VERSION );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseName() {
|
||||
return databaseName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMajorVersion() {
|
||||
return databaseMajorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMinorVersion() {
|
||||
return databaseMinorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverName() {
|
||||
return driverName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMajorVersion() {
|
||||
return driverMajorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMinorVersion() {
|
||||
return driverMinorVersion;
|
||||
}
|
||||
}
|
|
@ -26,8 +26,6 @@ package org.hibernate.engine.jdbc.dialect.internal;
|
|||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
@ -39,15 +37,18 @@ import org.hibernate.dialect.PostgreSQL9Dialect;
|
|||
import org.hibernate.dialect.SQLServer2005Dialect;
|
||||
import org.hibernate.dialect.SQLServer2008Dialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.dialect.resolver.DialectResolverTest;
|
||||
import org.hibernate.dialect.resolver.TestingDialectResolutionInfo;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit test of the {@link StandardDatabaseMetaDataDialectResolver} class.
|
||||
* Unit test of the {@link StandardDialectResolver} class.
|
||||
*
|
||||
* @author Bryan Turner
|
||||
*/
|
||||
public class StandardDatabaseMetaDataDialectResolverTest extends BaseUnitTestCase {
|
||||
public class StandardDialectResolverTest extends BaseUnitTestCase {
|
||||
|
||||
@Test
|
||||
public void testResolveDialectInternalForSQLServer2000()
|
||||
|
@ -131,15 +132,13 @@ public class StandardDatabaseMetaDataDialectResolverTest extends BaseUnitTestCas
|
|||
}
|
||||
|
||||
private static void runDialectTest(
|
||||
String productName, int majorVersion, int minorVersion,
|
||||
Class<? extends Dialect> expectedDialect) throws SQLException {
|
||||
DatabaseMetaData metaData = mock( DatabaseMetaData.class );
|
||||
when( metaData.getDatabaseProductName() ).thenReturn( productName );
|
||||
when( metaData.getDatabaseMajorVersion() ).thenReturn( majorVersion );
|
||||
when( metaData.getDatabaseMinorVersion() ).thenReturn( minorVersion );
|
||||
String productName,
|
||||
int majorVersion,
|
||||
int minorVersion,
|
||||
Class<? extends Dialect> expectedDialect) {
|
||||
TestingDialectResolutionInfo info = TestingDialectResolutionInfo.forDatabaseInfo( productName, majorVersion, minorVersion );
|
||||
|
||||
Dialect dialect = new StandardDatabaseMetaDataDialectResolver( StandardDatabaseInfoDialectResolver.INSTANCE )
|
||||
.resolveDialectInternal( metaData );
|
||||
Dialect dialect = StandardDialectResolver.INSTANCE.resolveDialect( info );
|
||||
|
||||
StringBuilder builder = new StringBuilder( productName ).append( " " )
|
||||
.append( majorVersion );
|
|
@ -30,7 +30,6 @@ import java.io.Writer;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -43,12 +42,13 @@ import org.jboss.logging.Logger;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseInfoDialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseMetaDataDialectResolutionInfoAdapter;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectFactory;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfoSource;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
||||
|
@ -98,7 +98,7 @@ public class JpaSchemaGenerator {
|
|||
/**
|
||||
* Perform the generation, as indicated by the settings
|
||||
*
|
||||
* @param hibernateConfiguration
|
||||
* @param hibernateConfiguration The hibernate configuration
|
||||
*/
|
||||
public void execute(Configuration hibernateConfiguration) {
|
||||
// First, determine the actions (if any) to be performed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -423,97 +423,75 @@ public class JpaSchemaGenerator {
|
|||
}
|
||||
|
||||
private static Dialect determineDialect(
|
||||
JdbcConnectionContext jdbcConnectionContext,
|
||||
Configuration hibernateConfiguration,
|
||||
final JdbcConnectionContext jdbcConnectionContext,
|
||||
final Configuration hibernateConfiguration,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
final String explicitDbName = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_NAME );
|
||||
final String explicitDbMajor = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_MAJOR_VERSION );
|
||||
final String explicitDbMinor = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_MINOR_VERSION );
|
||||
|
||||
if ( StringHelper.isNotEmpty( explicitDbName ) ) {
|
||||
serviceRegistry.getService( DatabaseInfoDialectResolver.class ).resolve(
|
||||
new DatabaseInfoDialectResolver.DatabaseInfo() {
|
||||
@Override
|
||||
public String getDatabaseName() {
|
||||
return explicitDbName;
|
||||
return serviceRegistry.getService( DialectFactory.class ).buildDialect(
|
||||
hibernateConfiguration.getProperties(),
|
||||
new DialectResolutionInfoSource() {
|
||||
@Override
|
||||
public DialectResolutionInfo getDialectResolutionInfo() {
|
||||
|
||||
// if the application supplied database name/version info, use that
|
||||
final String explicitDbName = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_NAME );
|
||||
if ( StringHelper.isNotEmpty( explicitDbName ) ) {
|
||||
final String explicitDbMajor = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_MAJOR_VERSION );
|
||||
final String explicitDbMinor = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_MINOR_VERSION );
|
||||
|
||||
return new DialectResolutionInfo() {
|
||||
@Override
|
||||
public String getDatabaseName() {
|
||||
return explicitDbName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMajorVersion() {
|
||||
return StringHelper.isEmpty( explicitDbMajor )
|
||||
? NO_VERSION
|
||||
: Integer.parseInt( explicitDbMajor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMinorVersion() {
|
||||
return StringHelper.isEmpty( explicitDbMinor )
|
||||
? NO_VERSION
|
||||
: Integer.parseInt( explicitDbMinor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMajorVersion() {
|
||||
return NO_VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDriverMinorVersion() {
|
||||
return NO_VERSION;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMajorVersion() {
|
||||
return StringHelper.isEmpty( explicitDbMajor )
|
||||
? NO_VERSION
|
||||
: Integer.parseInt( explicitDbMajor );
|
||||
// otherwise look at the connection, if provided (if not provided the call to
|
||||
// getJdbcConnection will already throw a meaningful exception)
|
||||
try {
|
||||
return new DatabaseMetaDataDialectResolutionInfoAdapter(
|
||||
jdbcConnectionContext.getJdbcConnection().getMetaData()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMinorVersion() {
|
||||
return StringHelper.isEmpty( explicitDbMinor )
|
||||
? NO_VERSION
|
||||
: Integer.parseInt( explicitDbMinor );
|
||||
catch ( SQLException sqlException ) {
|
||||
throw new HibernateException(
|
||||
"Unable to access java.sql.DatabaseMetaData to determine appropriate Dialect to use",
|
||||
sqlException
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return buildDialect( hibernateConfiguration, serviceRegistry, jdbcConnectionContext );
|
||||
}
|
||||
|
||||
private static Dialect buildDialect(
|
||||
Configuration hibernateConfiguration,
|
||||
ServiceRegistry serviceRegistry,
|
||||
JdbcConnectionContext jdbcConnectionContext) {
|
||||
// todo : a lot of copy/paste from the DialectFactory impl...
|
||||
final String dialectName = hibernateConfiguration.getProperty( org.hibernate.cfg.AvailableSettings.DIALECT );
|
||||
if ( dialectName != null ) {
|
||||
return constructDialect( dialectName, serviceRegistry );
|
||||
}
|
||||
else {
|
||||
return determineDialectBasedOnJdbcMetadata( jdbcConnectionContext, serviceRegistry );
|
||||
}
|
||||
}
|
||||
|
||||
private static Dialect constructDialect(String dialectName, ServiceRegistry serviceRegistry) {
|
||||
final Dialect dialect;
|
||||
final StrategySelector strategySelector = serviceRegistry.getService( StrategySelector.class );
|
||||
try {
|
||||
dialect = strategySelector.resolveStrategy( Dialect.class, dialectName );
|
||||
if ( dialect == null ) {
|
||||
throw new HibernateException( "Unable to construct requested dialect [" + dialectName + "]" );
|
||||
}
|
||||
return dialect;
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( "Unable to construct requested dialect [" + dialectName+ "]", e );
|
||||
}
|
||||
}
|
||||
|
||||
private static Dialect determineDialectBasedOnJdbcMetadata(
|
||||
JdbcConnectionContext jdbcConnectionContext,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
final DialectResolver dialectResolver = serviceRegistry.getService( DialectResolver.class );
|
||||
try {
|
||||
final DatabaseMetaData databaseMetaData = jdbcConnectionContext.getJdbcConnection().getMetaData();
|
||||
final Dialect dialect = dialectResolver.resolveDialect( databaseMetaData );
|
||||
|
||||
if ( dialect == null ) {
|
||||
throw new HibernateException(
|
||||
"Unable to determine Dialect to use [name=" + databaseMetaData.getDatabaseProductName() +
|
||||
", majorVersion=" + databaseMetaData.getDatabaseMajorVersion() +
|
||||
"]; user must register resolver or explicitly set 'hibernate.dialect'"
|
||||
);
|
||||
}
|
||||
|
||||
return dialect;
|
||||
}
|
||||
catch ( SQLException sqlException ) {
|
||||
throw new HibernateException(
|
||||
"Unable to access java.sql.DatabaseMetaData to determine appropriate Dialect to use",
|
||||
sqlException
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private static void doGeneration(
|
||||
|
|
Loading…
Reference in New Issue