[hibernate-commits] Hibernate SVN: r15342 - in core/branches/Branch_3_3/core/src: main/java/org/hibernate/dialect and 6 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Oct 13 11:16:22 EDT 2008


Author: steve.ebersole at jboss.com
Date: 2008-10-13 11:16:21 -0400 (Mon, 13 Oct 2008)
New Revision: 15342

Added:
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java
   core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/
   core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/Mocks.java
   core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/TestingDialects.java
   core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/
   core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java
   core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java
   core/branches/Branch_3_3/core/src/test/resources/
   core/branches/Branch_3_3/core/src/test/resources/log4j.properties
Removed:
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DialectFactory.java
Modified:
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/Environment.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
Log:
HHH-2293 : DialectResolver

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/Environment.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/Environment.java	2008-10-13 15:08:15 UTC (rev 15341)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/Environment.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -240,7 +240,14 @@
 	 * 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
 	 */
 	public static final String DEFAULT_SCHEMA = "hibernate.default_schema";

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2008-10-13 15:08:15 UTC (rev 15341)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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.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.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 @@
 
 		//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 @@
 				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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		settings.setStructuredCacheEntriesEnabled(useStructuredCacheEntries);
 
 		if (useQueryCache) settings.setQueryCacheFactory( createQueryCacheFactory(properties) );
-		
+
 		//SQL Exception converter:
-		
+
 		SQLExceptionConverter sqlExceptionConverter;
 		try {
 			sqlExceptionConverter = SQLExceptionConverterFactory.buildSQLExceptionConverter( dialect, properties );
@@ -302,13 +304,13 @@
 		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 @@
 		}
 	}
 
-	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 @@
 			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 @@
 			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 @@
 			}
 		}
 	}
-	
+
 	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 );
-	}
-	
 }

Deleted: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DialectFactory.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DialectFactory.java	2008-10-13 15:08:15 UTC (rev 15341)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DialectFactory.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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 + "]" );
-						}
-			        }
-		        }
-		);
-	}
-}

Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/AbstractDialectResolver.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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;
+}

Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicDialectResolver.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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;
+	}
+}

Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/BasicSQLExceptionConverter.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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 "???";
+		}
+	}
+}

Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectFactory.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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 );
+		}
+	}
+}

Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolver.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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;
+}

Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/DialectResolverSet.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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 );
+	}
+}

Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/resolver/StandardDialectResolver.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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;
+	}
+}

Added: core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/Mocks.java
===================================================================
--- core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/Mocks.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/Mocks.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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;
+	}
+}

Added: core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/TestingDialects.java
===================================================================
--- core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/TestingDialects.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/TestingDialects.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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 );
+		}
+	}
+
+}

Added: core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java
===================================================================
--- core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectFactoryTest.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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() );
+	}
+}

Added: core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java
===================================================================
--- core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/test/java/org/hibernate/dialect/resolver/DialectResolverTest.java	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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 );
+	}
+}

Added: core/branches/Branch_3_3/core/src/test/resources/log4j.properties
===================================================================
--- core/branches/Branch_3_3/core/src/test/resources/log4j.properties	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/test/resources/log4j.properties	2008-10-13 15:16:21 UTC (rev 15342)
@@ -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




More information about the hibernate-commits mailing list