HHH-2933 : DialectResolver
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15343 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
1c27ee9bb5
commit
13ddb15f29
|
@ -240,6 +240,13 @@ public final class Environment {
|
|||
* Hibernate SQL {@link org.hibernate.dialect.Dialect} class
|
||||
*/
|
||||
public static final String DIALECT ="hibernate.dialect";
|
||||
|
||||
/**
|
||||
* {@link org.hibernate.dialect.resolver.DialectResolver} classes to register with the
|
||||
* {@link org.hibernate.dialect.resolver.DialectFactory}
|
||||
*/
|
||||
public static final String DIALECT_RESOLVERS = "hibernate.dialect_resolvers";
|
||||
|
||||
/**
|
||||
* A default database schema (owner) name to use for unqualified tablenames
|
||||
*/
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
package org.hibernate.cfg;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -47,7 +46,7 @@ import org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge;
|
|||
import org.hibernate.connection.ConnectionProvider;
|
||||
import org.hibernate.connection.ConnectionProviderFactory;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.DialectFactory;
|
||||
import org.hibernate.dialect.resolver.DialectFactory;
|
||||
import org.hibernate.exception.SQLExceptionConverter;
|
||||
import org.hibernate.exception.SQLExceptionConverterFactory;
|
||||
import org.hibernate.hql.QueryTranslatorFactory;
|
||||
|
@ -64,23 +63,24 @@ import org.hibernate.util.ReflectHelper;
|
|||
import org.hibernate.util.StringHelper;
|
||||
|
||||
/**
|
||||
* Reads configuration properties and configures a <tt>Settings</tt> instance.
|
||||
* Reads configuration properties and builds a {@link Settings} instance.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class SettingsFactory implements Serializable {
|
||||
private static final Logger log = LoggerFactory.getLogger( SettingsFactory.class );
|
||||
private static final long serialVersionUID = -1194386144994524825L;
|
||||
|
||||
public static final String DEF_CACHE_REG_FACTORY = NoCachingRegionFactory.class.getName();
|
||||
private static final Logger log = LoggerFactory.getLogger(SettingsFactory.class);
|
||||
|
||||
protected SettingsFactory() {
|
||||
}
|
||||
|
||||
|
||||
public Settings buildSettings(Properties props) {
|
||||
Settings settings = new Settings();
|
||||
|
||||
|
||||
//SessionFactory name:
|
||||
|
||||
|
||||
String sessionFactoryName = props.getProperty(Environment.SESSION_FACTORY_NAME);
|
||||
settings.setSessionFactoryName(sessionFactoryName);
|
||||
|
||||
|
@ -91,17 +91,17 @@ public class SettingsFactory implements Serializable {
|
|||
|
||||
//Interrogate JDBC metadata
|
||||
|
||||
String databaseName = null;
|
||||
int databaseMajorVersion = 0;
|
||||
boolean metaSupportsScrollable = false;
|
||||
boolean metaSupportsGetGeneratedKeys = false;
|
||||
boolean metaSupportsBatchUpdates = false;
|
||||
boolean metaReportsDDLCausesTxnCommit = false;
|
||||
boolean metaReportsDDLInTxnSupported = true;
|
||||
Dialect dialect = null;
|
||||
|
||||
// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
|
||||
// The need for it is intended to be alleviated with 3.3 developement, thus it is
|
||||
// The need for it is intended to be alleviated with future developement, thus it is
|
||||
// not defined as an Environment constant...
|
||||
//
|
||||
// it is used to control whether we should consult the JDBC metadata to determine
|
||||
// certain Settings default values; it is useful to *not* do this when the database
|
||||
// may not be available (mainly in tools usage).
|
||||
|
@ -111,46 +111,48 @@ public class SettingsFactory implements Serializable {
|
|||
Connection conn = connections.getConnection();
|
||||
try {
|
||||
DatabaseMetaData meta = conn.getMetaData();
|
||||
databaseName = meta.getDatabaseProductName();
|
||||
databaseMajorVersion = getDatabaseMajorVersion(meta);
|
||||
log.info("RDBMS: " + databaseName + ", version: " + meta.getDatabaseProductVersion() );
|
||||
log.info("JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
|
||||
log.info( "RDBMS: " + meta.getDatabaseProductName() + ", version: " + meta.getDatabaseProductVersion() );
|
||||
log.info( "JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
|
||||
|
||||
metaSupportsScrollable = meta.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);
|
||||
dialect = DialectFactory.buildDialect( props, conn );
|
||||
|
||||
metaSupportsScrollable = meta.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE );
|
||||
metaSupportsBatchUpdates = meta.supportsBatchUpdates();
|
||||
metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
|
||||
metaReportsDDLInTxnSupported = !meta.dataDefinitionIgnoredInTransactions();
|
||||
metaSupportsGetGeneratedKeys = meta.supportsGetGeneratedKeys();
|
||||
metaSupportsGetGeneratedKeys = meta.supportsGetGeneratedKeys();
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
log.warn("Could not obtain connection metadata", sqle);
|
||||
catch ( SQLException sqle ) {
|
||||
log.warn( "Could not obtain connection metadata", sqle );
|
||||
}
|
||||
finally {
|
||||
connections.closeConnection(conn);
|
||||
connections.closeConnection( conn );
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle) {
|
||||
log.warn("Could not obtain connection to query metadata", sqle);
|
||||
catch ( SQLException sqle ) {
|
||||
log.warn( "Could not obtain connection to query metadata", sqle );
|
||||
dialect = DialectFactory.buildDialect( props );
|
||||
}
|
||||
catch (UnsupportedOperationException uoe) {
|
||||
catch ( UnsupportedOperationException uoe ) {
|
||||
// user supplied JDBC connections
|
||||
dialect = DialectFactory.buildDialect( props );
|
||||
}
|
||||
}
|
||||
else {
|
||||
dialect = DialectFactory.buildDialect( props );
|
||||
}
|
||||
|
||||
settings.setDataDefinitionImplicitCommit( metaReportsDDLCausesTxnCommit );
|
||||
settings.setDataDefinitionInTransactionSupported( metaReportsDDLInTxnSupported );
|
||||
settings.setDialect( dialect );
|
||||
|
||||
|
||||
//SQL Dialect:
|
||||
Dialect dialect = determineDialect( props, databaseName, databaseMajorVersion );
|
||||
settings.setDialect(dialect);
|
||||
|
||||
//use dialect default properties
|
||||
final Properties properties = new Properties();
|
||||
properties.putAll( dialect.getDefaultProperties() );
|
||||
properties.putAll(props);
|
||||
|
||||
properties.putAll( props );
|
||||
|
||||
// Transaction settings:
|
||||
|
||||
|
||||
TransactionFactory transactionFactory = createTransactionFactory(properties);
|
||||
settings.setTransactionFactory(transactionFactory);
|
||||
settings.setTransactionManagerLookup( createTransactionManagerLookup(properties) );
|
||||
|
@ -173,7 +175,7 @@ public class SettingsFactory implements Serializable {
|
|||
if (batchSize>0) log.info("JDBC batch updates for versioned data: " + enabledDisabled(jdbcBatchVersionedData) );
|
||||
settings.setJdbcBatchVersionedData(jdbcBatchVersionedData);
|
||||
settings.setBatcherFactory( createBatcherFactory(properties, batchSize) );
|
||||
|
||||
|
||||
boolean useScrollableResultSets = PropertiesHelper.getBoolean(Environment.USE_SCROLLABLE_RESULTSET, properties, metaSupportsScrollable);
|
||||
log.info("Scrollable result sets: " + enabledDisabled(useScrollableResultSets) );
|
||||
settings.setScrollableResultSetsEnabled(useScrollableResultSets);
|
||||
|
@ -224,7 +226,7 @@ public class SettingsFactory implements Serializable {
|
|||
boolean comments = PropertiesHelper.getBoolean(Environment.USE_SQL_COMMENTS, properties);
|
||||
log.info( "Generate SQL with comments: " + enabledDisabled(comments) );
|
||||
settings.setCommentsEnabled(comments);
|
||||
|
||||
|
||||
boolean orderUpdates = PropertiesHelper.getBoolean(Environment.ORDER_UPDATES, properties);
|
||||
log.info( "Order SQL updates by primary key: " + enabledDisabled(orderUpdates) );
|
||||
settings.setOrderUpdatesEnabled(orderUpdates);
|
||||
|
@ -232,9 +234,9 @@ public class SettingsFactory implements Serializable {
|
|||
boolean orderInserts = PropertiesHelper.getBoolean(Environment.ORDER_INSERTS, properties);
|
||||
log.info( "Order SQL inserts for batching: " + enabledDisabled( orderInserts ) );
|
||||
settings.setOrderInsertsEnabled( orderInserts );
|
||||
|
||||
|
||||
//Query parser settings:
|
||||
|
||||
|
||||
settings.setQueryTranslatorFactory( createQueryTranslatorFactory(properties) );
|
||||
|
||||
Map querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", properties);
|
||||
|
@ -244,7 +246,7 @@ public class SettingsFactory implements Serializable {
|
|||
boolean jpaqlCompliance = PropertiesHelper.getBoolean( Environment.JPAQL_STRICT_COMPLIANCE, properties, false );
|
||||
settings.setStrictJPAQLCompliance( jpaqlCompliance );
|
||||
log.info( "JPA-QL strict compliance: " + enabledDisabled( jpaqlCompliance ) );
|
||||
|
||||
|
||||
// Second-level / query cache:
|
||||
|
||||
boolean useSecondLevelCache = PropertiesHelper.getBoolean(Environment.USE_SECOND_LEVEL_CACHE, properties, true);
|
||||
|
@ -275,9 +277,9 @@ public class SettingsFactory implements Serializable {
|
|||
settings.setStructuredCacheEntriesEnabled(useStructuredCacheEntries);
|
||||
|
||||
if (useQueryCache) settings.setQueryCacheFactory( createQueryCacheFactory(properties) );
|
||||
|
||||
|
||||
//SQL Exception converter:
|
||||
|
||||
|
||||
SQLExceptionConverter sqlExceptionConverter;
|
||||
try {
|
||||
sqlExceptionConverter = SQLExceptionConverterFactory.buildSQLExceptionConverter( dialect, properties );
|
||||
|
@ -302,13 +304,13 @@ public class SettingsFactory implements Serializable {
|
|||
boolean useStatistics = PropertiesHelper.getBoolean(Environment.GENERATE_STATISTICS, properties);
|
||||
log.info( "Statistics: " + enabledDisabled(useStatistics) );
|
||||
settings.setStatisticsEnabled(useStatistics);
|
||||
|
||||
|
||||
boolean useIdentifierRollback = PropertiesHelper.getBoolean(Environment.USE_IDENTIFIER_ROLLBACK, properties);
|
||||
log.info( "Deleted entity synthetic identifier rollback: " + enabledDisabled(useIdentifierRollback) );
|
||||
settings.setIdentifierRollbackEnabled(useIdentifierRollback);
|
||||
|
||||
|
||||
//Schema export:
|
||||
|
||||
|
||||
String autoSchemaExport = properties.getProperty(Environment.HBM2DDL_AUTO);
|
||||
if ( "validate".equals(autoSchemaExport) ) settings.setAutoValidateSchema(true);
|
||||
if ( "update".equals(autoSchemaExport) ) settings.setAutoUpdateSchema(true);
|
||||
|
@ -348,24 +350,10 @@ public class SettingsFactory implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private int getDatabaseMajorVersion(DatabaseMetaData meta) {
|
||||
try {
|
||||
Method gdbmvMethod = DatabaseMetaData.class.getMethod("getDatabaseMajorVersion", null);
|
||||
return ( (Integer) gdbmvMethod.invoke(meta, null) ).intValue();
|
||||
}
|
||||
catch (NoSuchMethodException nsme) {
|
||||
return 0;
|
||||
}
|
||||
catch (Throwable t) {
|
||||
log.debug("could not get database version from JDBC metadata");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static String enabledDisabled(boolean value) {
|
||||
return value ? "enabled" : "disabled";
|
||||
}
|
||||
|
||||
|
||||
protected QueryCacheFactory createQueryCacheFactory(Properties properties) {
|
||||
String queryCacheFactoryClassName = PropertiesHelper.getString(
|
||||
Environment.QUERY_CACHE_FACTORY, properties, "org.hibernate.cache.StandardQueryCacheFactory"
|
||||
|
@ -401,7 +389,7 @@ public class SettingsFactory implements Serializable {
|
|||
throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties) {
|
||||
String className = PropertiesHelper.getString(
|
||||
Environment.QUERY_TRANSLATOR, properties, "org.hibernate.hql.ast.ASTQueryTranslatorFactory"
|
||||
|
@ -414,7 +402,7 @@ public class SettingsFactory implements Serializable {
|
|||
throw new HibernateException("could not instantiate QueryTranslatorFactory: " + className, cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected BatcherFactory createBatcherFactory(Properties properties, int batchSize) {
|
||||
String batcherClass = properties.getProperty(Environment.BATCH_STRATEGY);
|
||||
if (batcherClass==null) {
|
||||
|
@ -432,21 +420,17 @@ public class SettingsFactory implements Serializable {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected ConnectionProvider createConnectionProvider(Properties properties) {
|
||||
return ConnectionProviderFactory.newConnectionProvider(properties);
|
||||
}
|
||||
|
||||
|
||||
protected TransactionFactory createTransactionFactory(Properties properties) {
|
||||
return TransactionFactoryFactory.buildTransactionFactory(properties);
|
||||
}
|
||||
|
||||
|
||||
protected TransactionManagerLookup createTransactionManagerLookup(Properties properties) {
|
||||
return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);
|
||||
return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);
|
||||
}
|
||||
|
||||
private Dialect determineDialect(Properties props, String databaseName, int databaseMajorVersion) {
|
||||
return DialectFactory.buildDialect( props, databaseName, databaseMajorVersion );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.util.ReflectHelper;
|
||||
|
||||
/**
|
||||
* A factory for generating Dialect instances.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DialectFactory {
|
||||
|
||||
/**
|
||||
* Builds an appropriate Dialect instance.
|
||||
* <p/>
|
||||
* If a dialect is explicitly named in the incoming properties, it is used. Otherwise, the database name and version
|
||||
* (obtained from connection metadata) are used to make the dertemination.
|
||||
* <p/>
|
||||
* An exception is thrown if a dialect was not explicitly set and the database name is not known.
|
||||
*
|
||||
* @param props The configuration properties.
|
||||
* @param databaseName The name of the database product (obtained from metadata).
|
||||
* @param databaseMajorVersion The major version of the database product (obtained from metadata).
|
||||
*
|
||||
* @return The appropriate dialect.
|
||||
*
|
||||
* @throws HibernateException No dialect specified and database name not known.
|
||||
*/
|
||||
public static Dialect buildDialect(Properties props, String databaseName, int databaseMajorVersion)
|
||||
throws HibernateException {
|
||||
String dialectName = props.getProperty( Environment.DIALECT );
|
||||
if ( dialectName == null ) {
|
||||
return determineDialect( databaseName, databaseMajorVersion );
|
||||
}
|
||||
else {
|
||||
return buildDialect( dialectName );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the appropriate Dialect to use given the database product name
|
||||
* and major version.
|
||||
*
|
||||
* @param databaseName The name of the database product (obtained from metadata).
|
||||
* @param databaseMajorVersion The major version of the database product (obtained from metadata).
|
||||
*
|
||||
* @return An appropriate dialect instance.
|
||||
*/
|
||||
public static Dialect determineDialect(String databaseName, int databaseMajorVersion) {
|
||||
if ( databaseName == null ) {
|
||||
throw new HibernateException( "Hibernate Dialect must be explicitly set" );
|
||||
}
|
||||
|
||||
DatabaseDialectMapper mapper = ( DatabaseDialectMapper ) MAPPERS.get( databaseName );
|
||||
if ( mapper == null ) {
|
||||
throw new HibernateException( "Hibernate Dialect must be explicitly set for database: " + databaseName );
|
||||
}
|
||||
|
||||
String dialectName = mapper.getDialectClass( databaseMajorVersion );
|
||||
return buildDialect( dialectName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a dialect instance given the name of the class to use.
|
||||
*
|
||||
* @param dialectName The name of the dialect class.
|
||||
*
|
||||
* @return The dialect instance.
|
||||
*/
|
||||
public static Dialect buildDialect(String dialectName) {
|
||||
try {
|
||||
return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
|
||||
}
|
||||
catch ( ClassNotFoundException cnfe ) {
|
||||
throw new HibernateException( "Dialect class not found: " + dialectName );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new HibernateException( "Could not instantiate dialect class", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given database product name, instances of
|
||||
* DatabaseDialectMapper know which Dialect to use for different versions.
|
||||
*/
|
||||
public static interface DatabaseDialectMapper {
|
||||
public String getDialectClass(int majorVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple DatabaseDialectMapper for dialects which are independent
|
||||
* of the underlying database product version.
|
||||
*/
|
||||
public static class VersionInsensitiveMapper implements DatabaseDialectMapper {
|
||||
private String dialectClassName;
|
||||
|
||||
public VersionInsensitiveMapper(String dialectClassName) {
|
||||
this.dialectClassName = dialectClassName;
|
||||
}
|
||||
|
||||
public String getDialectClass(int majorVersion) {
|
||||
return dialectClassName;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : this is the stuff it'd be nice to move to a properties file or some other easily user-editable place
|
||||
private static final Map MAPPERS = new HashMap();
|
||||
static {
|
||||
// detectors...
|
||||
MAPPERS.put( "HSQL Database Engine", new VersionInsensitiveMapper( "org.hibernate.dialect.HSQLDialect" ) );
|
||||
MAPPERS.put( "H2", new VersionInsensitiveMapper( "org.hibernate.dialect.H2Dialect" ) );
|
||||
MAPPERS.put( "MySQL", new VersionInsensitiveMapper( "org.hibernate.dialect.MySQLDialect" ) );
|
||||
MAPPERS.put( "PostgreSQL", new VersionInsensitiveMapper( "org.hibernate.dialect.PostgreSQLDialect" ) );
|
||||
MAPPERS.put( "Apache Derby", new VersionInsensitiveMapper( "org.hibernate.dialect.DerbyDialect" ) );
|
||||
|
||||
MAPPERS.put( "Ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
|
||||
MAPPERS.put( "ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
|
||||
MAPPERS.put( "INGRES", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
|
||||
|
||||
MAPPERS.put( "Microsoft SQL Server Database", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
|
||||
MAPPERS.put( "Microsoft SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
|
||||
MAPPERS.put( "Sybase SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
|
||||
MAPPERS.put( "Adaptive Server Enterprise", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
|
||||
|
||||
MAPPERS.put( "Informix Dynamic Server", new VersionInsensitiveMapper( "org.hibernate.dialect.InformixDialect" ) );
|
||||
|
||||
// thanks goodness for "universal" databases...
|
||||
MAPPERS.put( "DB2/NT", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
|
||||
MAPPERS.put( "DB2/LINUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
|
||||
MAPPERS.put( "DB2/6000", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
|
||||
MAPPERS.put( "DB2/HPUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
|
||||
MAPPERS.put( "DB2/SUN", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
|
||||
MAPPERS.put( "DB2/LINUX390", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
|
||||
MAPPERS.put( "DB2/AIX64", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
|
||||
|
||||
MAPPERS.put(
|
||||
"Oracle",
|
||||
new DatabaseDialectMapper() {
|
||||
public String getDialectClass(int majorVersion) {
|
||||
switch ( majorVersion ) {
|
||||
case 8: return Oracle8iDialect.class.getName();
|
||||
case 9: return Oracle9iDialect.class.getName();
|
||||
case 10: return Oracle10gDialect.class.getName();
|
||||
default: throw new HibernateException( "unknown Oracle major version [" + majorVersion + "]" );
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
import org.hibernate.JDBCException;
|
||||
|
||||
/**
|
||||
* A templated resolver impl which delegates to the {@link #resolveDialectInternal} method
|
||||
* and handles any thrown {@link SQLException}s.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractDialectResolver implements DialectResolver {
|
||||
private static final Logger log = LoggerFactory.getLogger( AbstractDialectResolver.class );
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p/>
|
||||
* Here we template the resolution, delegating to {@link #resolveDialectInternal} and handling
|
||||
* {@link java.sql.SQLException}s properly.
|
||||
*/
|
||||
public final Dialect resolveDialect(DatabaseMetaData metaData) {
|
||||
try {
|
||||
return resolveDialectInternal( metaData );
|
||||
}
|
||||
catch ( SQLException sqlException ) {
|
||||
JDBCException jdbcException = BasicSQLExceptionConverter.INSTANCE.convert( sqlException );
|
||||
if ( jdbcException instanceof JDBCConnectionException ) {
|
||||
throw jdbcException;
|
||||
}
|
||||
else {
|
||||
log.warn( BasicSQLExceptionConverter.MSG + " : " + sqlException.getMessage() );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch ( Throwable t ) {
|
||||
log.warn( "Error executing resolver [" + 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;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Intended as support for custom resolvers.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicDialectResolver extends AbstractDialectResolver {
|
||||
public static final int VERSION_INSENSITIVE_VERSION = -9999;
|
||||
|
||||
private final String matchingName;
|
||||
private final int matchingVersion;
|
||||
private final Class dialectClass;
|
||||
|
||||
public BasicDialectResolver(String matchingName, Class dialectClass) {
|
||||
this( matchingName, VERSION_INSENSITIVE_VERSION, dialectClass );
|
||||
}
|
||||
|
||||
public BasicDialectResolver(String matchingName, int matchingVersion, Class dialectClass) {
|
||||
this.matchingName = matchingName;
|
||||
this.matchingVersion = matchingVersion;
|
||||
this.dialectClass = dialectClass;
|
||||
}
|
||||
|
||||
protected final Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
|
||||
final String databaseName = metaData.getDatabaseProductName();
|
||||
final int databaseMajorVersion = metaData.getDatabaseMajorVersion();
|
||||
|
||||
if ( matchingName.equalsIgnoreCase( databaseName )
|
||||
&& ( matchingVersion == VERSION_INSENSITIVE_VERSION || matchingVersion == databaseMajorVersion ) ) {
|
||||
try {
|
||||
return ( Dialect ) dialectClass.newInstance();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
// conceivable that the dialect ctor could throw HibernateExceptions, so don't re-wrap
|
||||
throw e;
|
||||
}
|
||||
catch ( Throwable t ) {
|
||||
throw new HibernateException(
|
||||
"Could not instantiate specified Dialect class [" + dialectClass.getName() + "]",
|
||||
t
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.sql.SQLException;
|
||||
|
||||
import org.hibernate.exception.SQLStateConverter;
|
||||
import org.hibernate.exception.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.JDBCException;
|
||||
|
||||
/**
|
||||
* A helper to centralize conversion of {@link java.sql.SQLException}s to {@link org.hibernate.JDBCException}s.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicSQLExceptionConverter {
|
||||
public static final BasicSQLExceptionConverter INSTANCE = new BasicSQLExceptionConverter();
|
||||
public static final String MSG = "Unable to query java.sql.DatabaseMetaData";
|
||||
|
||||
private static final SQLStateConverter CONVERTER = new SQLStateConverter( new ConstraintNameExtracter() );
|
||||
|
||||
/**
|
||||
* Perform a conversion.
|
||||
*
|
||||
* @param sqlException The exception to convert.
|
||||
* @return The converted exception.
|
||||
*/
|
||||
public JDBCException convert(SQLException sqlException) {
|
||||
return CONVERTER.convert( sqlException, MSG, null );
|
||||
}
|
||||
|
||||
private static class ConstraintNameExtracter implements ViolatedConstraintNameExtracter {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.dialect.resolver.DialectResolver;
|
||||
import org.hibernate.dialect.resolver.DialectResolverSet;
|
||||
import org.hibernate.dialect.resolver.StandardDialectResolver;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.util.ReflectHelper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A factory for generating Dialect instances.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Tomoto Shimizu Washio
|
||||
*/
|
||||
public class DialectFactory {
|
||||
private static final Logger log = LoggerFactory.getLogger( DialectFactory.class );
|
||||
|
||||
private static DialectResolverSet DIALECT_RESOLVERS = new DialectResolverSet();
|
||||
|
||||
static {
|
||||
// register the standard dialect resolver
|
||||
DIALECT_RESOLVERS.addResolver( new StandardDialectResolver() );
|
||||
|
||||
// register resolvers set via Environment property
|
||||
String userSpecifedResolverSetting = Environment.getProperties().getProperty( Environment.DIALECT_RESOLVERS );
|
||||
if ( userSpecifedResolverSetting != null ) {
|
||||
String[] userSpecifedResolvers = userSpecifedResolverSetting.split( "\\s+" );
|
||||
for ( int i = 0; i < userSpecifedResolvers.length; i++ ) {
|
||||
registerDialectResolver( userSpecifedResolvers[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ static void registerDialectResolver(String resolverName) {
|
||||
try {
|
||||
DialectResolver resolver = ( DialectResolver ) ReflectHelper.classForName( resolverName ).newInstance();
|
||||
DIALECT_RESOLVERS.addResolverAtFirst( resolver );
|
||||
}
|
||||
catch ( ClassNotFoundException cnfe ) {
|
||||
log.warn( "Dialect resolver class not found: " + resolverName );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
log.warn( "Could not instantiate dialect resolver class", e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an appropriate Dialect instance.
|
||||
* <p/>
|
||||
* If a dialect is explicitly named in the incoming properties, it is used. Otherwise, it is
|
||||
* determined by dialect resolvers based on the passed connection.
|
||||
* <p/>
|
||||
* An exception is thrown if a dialect was not explicitly set and no resolver could make
|
||||
* the determination from the given connection.
|
||||
*
|
||||
* @param properties The configuration properties.
|
||||
* @param connection The configured connection.
|
||||
* @return The appropriate dialect instance.
|
||||
* @throws HibernateException No dialect specified and no resolver could make the determination.
|
||||
*/
|
||||
public static Dialect buildDialect(Properties properties, Connection connection) throws HibernateException {
|
||||
String dialectName = properties.getProperty( Environment.DIALECT );
|
||||
if ( dialectName == null ) {
|
||||
return determineDialect( connection );
|
||||
}
|
||||
else {
|
||||
return constructDialect( dialectName );
|
||||
}
|
||||
}
|
||||
|
||||
public static Dialect buildDialect(Properties properties) {
|
||||
String dialectName = properties.getProperty( Environment.DIALECT );
|
||||
if ( dialectName == null ) {
|
||||
throw new HibernateException( "'hibernate.dialect' must be set when no Connection avalable" );
|
||||
}
|
||||
return constructDialect( dialectName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the appropriate Dialect to use given the connection.
|
||||
*
|
||||
* @param connection The configured connection.
|
||||
* @return The appropriate dialect instance.
|
||||
*
|
||||
* @throws HibernateException No connection given or no resolver could make
|
||||
* the determination from the given connection.
|
||||
*/
|
||||
private static Dialect determineDialect(Connection connection) {
|
||||
if ( connection == null ) {
|
||||
throw new HibernateException( "Connection cannot be null when 'hibernate.dialect' not set" );
|
||||
}
|
||||
|
||||
try {
|
||||
final DatabaseMetaData databaseMetaData = connection.getMetaData();
|
||||
final Dialect dialect = DIALECT_RESOLVERS.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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a dialect instance given the name of the class to use.
|
||||
*
|
||||
* @param dialectName The name of the dialect class.
|
||||
*
|
||||
* @return The dialect instance.
|
||||
*/
|
||||
public static Dialect constructDialect(String dialectName) {
|
||||
try {
|
||||
return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
|
||||
}
|
||||
catch ( ClassNotFoundException cnfe ) {
|
||||
throw new HibernateException( "Dialect class not found: " + dialectName, cnfe );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new HibernateException( "Could not instantiate dialect class", e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
|
||||
/**
|
||||
* Contract for determining the {@link Dialect} to use based on a JDBC {@link Connection}.
|
||||
*
|
||||
* @author Tomoto Shimizu Washio
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface DialectResolver {
|
||||
/**
|
||||
* Determine the {@link Dialect} to use based on the given JDBC {@link DatabaseMetaData}. Implementations are
|
||||
* expected to return the {@link Dialect} instance to use, or null if the {@link DatabaseMetaData} does not match
|
||||
* the criteria handled by this impl.
|
||||
*
|
||||
* @param metaData The JDBC metadata.
|
||||
* @return The dialect to use, or null.
|
||||
* @throws JDBCConnectionException Indicates a 'non transient connection problem', which indicates that
|
||||
* we should stop resolution attempts.
|
||||
*/
|
||||
public Dialect resolveDialect(DatabaseMetaData metaData) throws JDBCConnectionException;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.sql.DatabaseMetaData;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
|
||||
/**
|
||||
* A {@link DialectResolver} implementation which coordinates resolution by delegating to its
|
||||
* registered sub-resolvers. Sub-resolvers may be registered by calling either {@link #addResolver} or
|
||||
* {@link #addResolverAtFirst}.
|
||||
*
|
||||
* @author Tomoto Shimizu Washio
|
||||
*/
|
||||
public class DialectResolverSet implements DialectResolver {
|
||||
private static Logger log = LoggerFactory.getLogger( DialectResolverSet.class );
|
||||
|
||||
private List resolvers = new ArrayList();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Dialect resolveDialect(DatabaseMetaData metaData) {
|
||||
Iterator i = resolvers.iterator();
|
||||
while ( i.hasNext() ) {
|
||||
final DialectResolver resolver = ( DialectResolver ) i.next();
|
||||
try {
|
||||
Dialect dialect = resolver.resolveDialect( metaData );
|
||||
if ( dialect != null ) {
|
||||
return dialect;
|
||||
}
|
||||
}
|
||||
catch ( JDBCConnectionException e ) {
|
||||
throw e;
|
||||
}
|
||||
catch ( Throwable t ) {
|
||||
log.info( "sub-resolver threw unexpected exception, continuing to next : " + t.getMessage() );
|
||||
}
|
||||
}
|
||||
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 );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.dialect.IngresDialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
import org.hibernate.dialect.InformixDialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
import org.hibernate.dialect.Oracle10gDialect;
|
||||
import org.hibernate.dialect.Oracle9iDialect;
|
||||
import org.hibernate.dialect.Oracle8iDialect;
|
||||
|
||||
/**
|
||||
* The standard Hibernate resolver.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardDialectResolver extends AbstractDialectResolver{
|
||||
private static final Logger log = LoggerFactory.getLogger( StandardDialectResolver.class );
|
||||
|
||||
protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
|
||||
String databaseName = metaData.getDatabaseProductName();
|
||||
int databaseMajorVersion = metaData.getDatabaseMajorVersion();
|
||||
|
||||
if ( "HSQL Database Engine".equals( databaseName ) ) {
|
||||
return new HSQLDialect();
|
||||
}
|
||||
|
||||
if ( "H2".equals( databaseName ) ) {
|
||||
return new H2Dialect();
|
||||
}
|
||||
|
||||
if ( "MySQL".equals( databaseName ) ) {
|
||||
return new MySQLDialect();
|
||||
}
|
||||
|
||||
if ( "PostgreSQL".equals( databaseName ) ) {
|
||||
return new PostgreSQLDialect();
|
||||
}
|
||||
|
||||
if ( "Apache Derby".equals( databaseName ) ) {
|
||||
return new DerbyDialect();
|
||||
}
|
||||
|
||||
if ( "ingres".equalsIgnoreCase( databaseName ) ) {
|
||||
return new IngresDialect();
|
||||
}
|
||||
|
||||
if ( databaseName.startsWith( "Microsoft SQL Server" ) ) {
|
||||
return new SQLServerDialect();
|
||||
}
|
||||
|
||||
if ( "Sybase SQL Server".equals( databaseName ) || "Adaptive Server Enterprise".equals( databaseName ) ) {
|
||||
return new SybaseDialect();
|
||||
}
|
||||
|
||||
if ( "Informix Dynamic Server".equals( databaseName ) ) {
|
||||
return new InformixDialect();
|
||||
}
|
||||
|
||||
if ( databaseName.startsWith( "DB2/" ) ) {
|
||||
return new DB2Dialect();
|
||||
}
|
||||
|
||||
if ( "Oracle".equals( databaseName ) ) {
|
||||
switch ( databaseMajorVersion ) {
|
||||
case 11:
|
||||
log.warn( "Oracle 11g is not yet fully supported; using 10g dialect" );
|
||||
return new Oracle10gDialect();
|
||||
case 10:
|
||||
return new Oracle10gDialect();
|
||||
case 9:
|
||||
return new Oracle9iDialect();
|
||||
case 8:
|
||||
return new Oracle8iDialect();
|
||||
default:
|
||||
log.warn( "unknown Oracle major version [" + databaseMajorVersion + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Mocks {
|
||||
|
||||
public static Connection createConnection(String dbName, int version) {
|
||||
DatabaseMetaDataHandler metadataHandler = new DatabaseMetaDataHandler( dbName, version );
|
||||
ConnectionHandler connectionHandler = new ConnectionHandler();
|
||||
|
||||
DatabaseMetaData metadataProxy = ( DatabaseMetaData ) Proxy.newProxyInstance(
|
||||
ClassLoader.getSystemClassLoader(),
|
||||
new Class[] { DatabaseMetaData.class },
|
||||
metadataHandler
|
||||
);
|
||||
|
||||
Connection connectionProxy = ( Connection ) Proxy.newProxyInstance(
|
||||
ClassLoader.getSystemClassLoader(),
|
||||
new Class[] { Connection.class },
|
||||
connectionHandler
|
||||
);
|
||||
|
||||
metadataHandler.setConnectionProxy( connectionProxy );
|
||||
connectionHandler.setMetadataProxy( metadataProxy );
|
||||
|
||||
return connectionProxy;
|
||||
}
|
||||
|
||||
private static class ConnectionHandler implements InvocationHandler {
|
||||
private DatabaseMetaData metadataProxy;
|
||||
|
||||
public void setMetadataProxy(DatabaseMetaData metadataProxy) {
|
||||
this.metadataProxy = metadataProxy;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
final String methodName = method.getName();
|
||||
if ( "getMetaData".equals( methodName ) ) {
|
||||
return metadataProxy;
|
||||
}
|
||||
|
||||
if ( "toString".equals( methodName ) ) {
|
||||
return "Connection proxy [@" + hashCode() + "]";
|
||||
}
|
||||
|
||||
if ( "hashCode".equals( methodName ) ) {
|
||||
return new Integer( this.hashCode() );
|
||||
}
|
||||
|
||||
if ( canThrowSQLException( method ) ) {
|
||||
throw new SQLException();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class DatabaseMetaDataHandler implements InvocationHandler {
|
||||
private final String databaseName;
|
||||
private final int majorVersion;
|
||||
|
||||
private Connection connectionProxy;
|
||||
|
||||
public void setConnectionProxy(Connection connectionProxy) {
|
||||
this.connectionProxy = connectionProxy;
|
||||
}
|
||||
|
||||
private DatabaseMetaDataHandler(String databaseName, int majorVersion) {
|
||||
this.databaseName = databaseName;
|
||||
this.majorVersion = majorVersion;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
final String methodName = method.getName();
|
||||
if ( "getDatabaseProductName".equals( methodName ) ) {
|
||||
return databaseName;
|
||||
}
|
||||
|
||||
if ( "getDatabaseMajorVersion".equals( methodName ) ) {
|
||||
return new Integer( majorVersion );
|
||||
}
|
||||
|
||||
if ( "getConnection".equals( methodName ) ) {
|
||||
return connectionProxy;
|
||||
}
|
||||
|
||||
if ( "toString".equals( methodName ) ) {
|
||||
return "DatabaseMetaData proxy [db-name=" + databaseName + ", version=" + majorVersion + "]";
|
||||
}
|
||||
|
||||
if ( "hashCode".equals( methodName ) ) {
|
||||
return new Integer( this.hashCode() );
|
||||
}
|
||||
|
||||
if ( canThrowSQLException( method ) ) {
|
||||
throw new SQLException();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean canThrowSQLException(Method method) {
|
||||
final Class[] exceptions = method.getExceptionTypes();
|
||||
for ( int i = 0; i < exceptions.length; i++ ) {
|
||||
if ( SQLException.class.isAssignableFrom( exceptions[i] ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
||||
import org.hibernate.dialect.resolver.AbstractDialectResolver;
|
||||
import org.hibernate.dialect.resolver.BasicDialectResolver;
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TestingDialects {
|
||||
|
||||
public static class MyDialect1 extends Dialect {
|
||||
}
|
||||
|
||||
public static class MyDialect21 extends Dialect {
|
||||
}
|
||||
|
||||
public static class MyDialect22 extends Dialect {
|
||||
}
|
||||
|
||||
public static class MySpecialDB2Dialect extends Dialect {
|
||||
}
|
||||
|
||||
public static class MyDialectResolver1 extends AbstractDialectResolver {
|
||||
protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
|
||||
String databaseName = metaData.getDatabaseProductName();
|
||||
int databaseMajorVersion = metaData.getDatabaseMajorVersion();
|
||||
if ( "MyDatabase1".equals( databaseName ) ) {
|
||||
return new MyDialect1();
|
||||
}
|
||||
if ( "MyDatabase2".equals( databaseName ) ) {
|
||||
if ( databaseMajorVersion >= 2 ) {
|
||||
return new MyDialect22();
|
||||
}
|
||||
if ( databaseMajorVersion >= 1 ) {
|
||||
return new MyDialect21();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyDialectResolver2 extends BasicDialectResolver {
|
||||
public MyDialectResolver2() {
|
||||
super( "MyTrickyDatabase1", MyDialect1.class );
|
||||
}
|
||||
}
|
||||
|
||||
public static class ErrorDialectResolver1 extends AbstractDialectResolver {
|
||||
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 AbstractDialectResolver {
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.util.Properties;
|
||||
import java.sql.Connection;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.dialect.resolver.DialectFactory;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.dialect.IngresDialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
import org.hibernate.dialect.InformixDialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
import org.hibernate.dialect.Oracle8iDialect;
|
||||
import org.hibernate.dialect.Oracle9iDialect;
|
||||
import org.hibernate.dialect.Oracle10gDialect;
|
||||
import org.hibernate.dialect.TestingDialects;
|
||||
import org.hibernate.dialect.Mocks;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DialectFactoryTest extends TestCase {
|
||||
public DialectFactoryTest(String name) {
|
||||
super( name );
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new TestSuite( DialectFactoryTest.class );
|
||||
}
|
||||
|
||||
public void testBuildDialectByClass() {
|
||||
assertEquals(
|
||||
HSQLDialect.class,
|
||||
DialectFactory.constructDialect( "org.hibernate.dialect.HSQLDialect" ).getClass()
|
||||
);
|
||||
|
||||
try {
|
||||
DialectFactory.constructDialect( "org.hibernate.dialect.NoSuchDialect" );
|
||||
fail();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
assertEquals( "unexpected exception type", e.getCause().getClass(), ClassNotFoundException.class );
|
||||
}
|
||||
|
||||
try {
|
||||
DialectFactory.constructDialect( "java.lang.Object" );
|
||||
fail();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
assertEquals( "unexpected exception type", e.getCause().getClass(), ClassCastException.class );
|
||||
}
|
||||
}
|
||||
|
||||
public void testBuildDialectByProperties() {
|
||||
Properties props = new Properties();
|
||||
|
||||
try {
|
||||
DialectFactory.buildDialect( props, null );
|
||||
fail();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
assertNull( e.getCause() );
|
||||
}
|
||||
|
||||
props.setProperty( Environment.DIALECT, "org.hibernate.dialect.HSQLDialect" );
|
||||
assertTrue( DialectFactory.buildDialect( props, null ) instanceof HSQLDialect );
|
||||
}
|
||||
|
||||
public void testPreregisteredDialects() {
|
||||
testDetermination( "HSQL Database Engine", HSQLDialect.class );
|
||||
testDetermination( "H2", H2Dialect.class );
|
||||
testDetermination( "MySQL", MySQLDialect.class );
|
||||
testDetermination( "PostgreSQL", PostgreSQLDialect.class );
|
||||
testDetermination( "Apache Derby", DerbyDialect.class );
|
||||
testDetermination( "Ingres", IngresDialect.class );
|
||||
testDetermination( "ingres", IngresDialect.class );
|
||||
testDetermination( "INGRES", IngresDialect.class );
|
||||
testDetermination( "Microsoft SQL Server Database", SQLServerDialect.class );
|
||||
testDetermination( "Microsoft SQL Server", SQLServerDialect.class );
|
||||
testDetermination( "Sybase SQL Server", SybaseDialect.class );
|
||||
testDetermination( "Adaptive Server Enterprise", SybaseDialect.class );
|
||||
testDetermination( "Informix Dynamic Server", InformixDialect.class );
|
||||
testDetermination( "DB2/NT", DB2Dialect.class );
|
||||
testDetermination( "DB2/LINUX", DB2Dialect.class );
|
||||
testDetermination( "DB2/6000", DB2Dialect.class );
|
||||
testDetermination( "DB2/HPUX", DB2Dialect.class );
|
||||
testDetermination( "DB2/SUN", DB2Dialect.class );
|
||||
testDetermination( "DB2/LINUX390", DB2Dialect.class );
|
||||
testDetermination( "DB2/AIX64", DB2Dialect.class );
|
||||
testDetermination( "Oracle", 8, Oracle8iDialect.class );
|
||||
testDetermination( "Oracle", 9, Oracle9iDialect.class );
|
||||
testDetermination( "Oracle", 10, Oracle10gDialect.class );
|
||||
testDetermination( "Oracle", 11, Oracle10gDialect.class );
|
||||
}
|
||||
|
||||
public void testCustomDialects() {
|
||||
DialectFactory.registerDialectResolver( TestingDialects.MyDialectResolver1.class.getName() );
|
||||
DialectFactory.registerDialectResolver( TestingDialects.MyDialectResolver2.class.getName() );
|
||||
DialectFactory.registerDialectResolver( TestingDialects.ErrorDialectResolver1.class.getName() );
|
||||
DialectFactory.registerDialectResolver( TestingDialects.ErrorDialectResolver2.class.getName() );
|
||||
DialectFactory.registerDialectResolver( TestingDialects.MyOverridingDialectResolver1.class.getName() );
|
||||
DialectFactory.registerDialectResolver( "org.hibernate.dialect.NoSuchDialectResolver" );
|
||||
DialectFactory.registerDialectResolver( "java.lang.Object" );
|
||||
|
||||
|
||||
testDetermination( "MyDatabase1", TestingDialects.MyDialect1.class );
|
||||
testDetermination( "MyDatabase2", 1, TestingDialects.MyDialect21.class );
|
||||
testDetermination( "MyTrickyDatabase1", TestingDialects.MyDialect1.class );
|
||||
|
||||
// This should be mapped to DB2Dialect by default, but actually it will be
|
||||
// my custom dialect because I have registered MyOverridingDialectResolver1.
|
||||
testDetermination( "DB2/MySpecialPlatform", TestingDialects.MySpecialDB2Dialect.class );
|
||||
|
||||
try {
|
||||
testDetermination( "ErrorDatabase1", Void.TYPE );
|
||||
fail();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
// log.info( "Expected SQL error in resolveDialect and ignored", e );
|
||||
}
|
||||
|
||||
try {
|
||||
testDetermination( "ErrorDatabase2", Void.TYPE );
|
||||
fail();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
// log.info( "Expected runtime error in resolveDialect", e );
|
||||
}
|
||||
}
|
||||
|
||||
public void testDialectNotFound() {
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
DialectFactory.buildDialect( properties, Mocks.createConnection( "NoSuchDatabase", 666 ) );
|
||||
fail();
|
||||
}
|
||||
catch ( HibernateException e ) {
|
||||
assertNull( e.getCause() );
|
||||
}
|
||||
}
|
||||
|
||||
private void testDetermination(String databaseName, Class clazz) {
|
||||
testDetermination( databaseName, -9999, clazz );
|
||||
}
|
||||
|
||||
private void testDetermination(String databaseName, int databaseMajorVersion, Class clazz) {
|
||||
Properties properties = new Properties();
|
||||
Connection conn = Mocks.createConnection( databaseName, databaseMajorVersion );
|
||||
assertEquals( clazz, DialectFactory.buildDialect( properties, conn ).getClass() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
*
|
||||
* 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 java.sql.SQLException;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.TestingDialects;
|
||||
import org.hibernate.dialect.Mocks;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DialectResolverTest extends TestCase {
|
||||
|
||||
public DialectResolverTest(String name) {
|
||||
super( name );
|
||||
}
|
||||
|
||||
public void testDialects() throws Exception {
|
||||
DialectResolverSet resolvers = new DialectResolverSet();
|
||||
|
||||
resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver1() );
|
||||
resolvers.addResolverAtFirst( new TestingDialects.MyDialectResolver2() );
|
||||
|
||||
testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
|
||||
testDetermination( resolvers, "MyDatabase1", 2, TestingDialects.MyDialect1.class );
|
||||
testDetermination( resolvers, "MyDatabase2", 0, null );
|
||||
testDetermination( resolvers, "MyDatabase2", 1, TestingDialects.MyDialect21.class );
|
||||
testDetermination( resolvers, "MyDatabase2", 2, TestingDialects.MyDialect22.class );
|
||||
testDetermination( resolvers, "MyDatabase2", 3, TestingDialects.MyDialect22.class );
|
||||
testDetermination( resolvers, "MyDatabase3", 1, null );
|
||||
testDetermination( resolvers, "MyTrickyDatabase1", 1, TestingDialects.MyDialect1.class );
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
public void testBasicDialectResolver() throws Exception {
|
||||
DialectResolverSet resolvers = new DialectResolverSet();
|
||||
// Simulating MyDialectResolver1 by BasicDialectResolvers
|
||||
resolvers.addResolver( new BasicDialectResolver( "MyDatabase1", TestingDialects.MyDialect1.class ) );
|
||||
resolvers.addResolver( new BasicDialectResolver( "MyDatabase2", 1, TestingDialects.MyDialect21.class ) );
|
||||
resolvers.addResolver( new BasicDialectResolver( "MyDatabase2", 2, TestingDialects.MyDialect22.class ) );
|
||||
resolvers.addResolver( new BasicDialectResolver( "ErrorDatabase1", Object.class ) );
|
||||
testDetermination( resolvers, "MyDatabase1", 1, TestingDialects.MyDialect1.class );
|
||||
|
||||
testDetermination( resolvers, "MyDatabase1", 2, TestingDialects.MyDialect1.class );
|
||||
testDetermination( resolvers, "MyDatabase2", 0, null );
|
||||
testDetermination( resolvers, "MyDatabase2", 1, TestingDialects.MyDialect21.class );
|
||||
testDetermination( resolvers, "MyDatabase2", 2, TestingDialects.MyDialect22.class );
|
||||
testDetermination( resolvers, "ErrorDatabase1", 0, null );
|
||||
}
|
||||
|
||||
|
||||
private void testDetermination(
|
||||
DialectResolver resolver,
|
||||
String databaseName,
|
||||
int version,
|
||||
Class dialectClass) throws SQLException {
|
||||
Dialect dialect = resolver.resolveDialect( Mocks.createConnection( databaseName, version ).getMetaData() );
|
||||
if ( dialectClass == null ) {
|
||||
assertEquals( null, dialect );
|
||||
}
|
||||
else {
|
||||
assertEquals( dialectClass, dialect.getClass() );
|
||||
}
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new TestSuite( DialectResolverTest.class );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# Hibernate, Relational Persistence for Idiomatic Java
|
||||
#
|
||||
# Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.Target=System.out
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
|
||||
|
||||
log4j.rootLogger=info, stdout
|
||||
|
||||
log4j.logger.org.hibernate.test=info
|
||||
log4j.logger.org.hibernate.tool.hbm2ddl=debug
|
Loading…
Reference in New Issue