From 479bc0bb5a932b40040eb0ee41d1eeedcec40a5b Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Tue, 27 Aug 2013 18:47:30 -0400 Subject: [PATCH] HHH-6446 Integrate new metamodel into SchemaValidator --- .../java/org/hibernate/dialect/Dialect.java | 9 + .../java/org/hibernate/dialect/H2Dialect.java | 5 + .../hibernate/dialect/Oracle8iDialect.java | 5 + ...er.java => DefaultSchemaNameResolver.java} | 12 +- .../env/internal/JdbcEnvironmentImpl.java | 10 +- .../NormalizingIdentifierHelperImpl.java | 10 +- .../engine/jdbc/env/spi/JdbcEnvironment.java | 3 + .../jdbc/env/spi/SchemaNameResolver.java | 5 +- .../DefaultIdentifierGeneratorFactory.java | 12 +- .../metamodel/spi/relational/Column.java | 18 +- .../tool/hbm2ddl/SchemaValidator.java | 74 +++++-- ...StandardJdbcDatabaseMetaDataExtractor.java | 16 +- .../spi/DatabaseInformationBuilder.java | 6 + .../HibernateSchemaManagementTool.java | 18 +- .../schema/internal/SchemaValidatorImpl.java | 10 +- .../internal/StandardTableExporter.java | 25 +-- .../common/BasicTestingJdbcServiceImpl.java | 6 + .../SynonymValidationTest.java | 197 ++++++++---------- 18 files changed, 269 insertions(+), 172 deletions(-) rename hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/{TemporarySchemaNameResolver.java => DefaultSchemaNameResolver.java} (80%) mode change 100755 => 100644 hibernate-core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 81ccf740eb..912a6a5c53 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -2023,6 +2023,15 @@ public abstract class Dialect implements ConversionContext { public String getDropSchemaCommand(String schemaName) { return "drop schema " + schemaName; } + + /** + * Get the SQL command used to retrieve the current schema name + * + * @return The current schema retrieval SQL + */ + public String getCurrentSchemaCommand() { + return null; + } /** * Does this dialect support the ALTER TABLE syntax? diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java index f0fc04be42..2a42a29f04 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java @@ -422,4 +422,9 @@ public class H2Dialect extends Dialect { // see http://groups.google.com/group/h2-database/browse_thread/thread/562d8a49e2dabe99?hl=en return true; } + + @Override + public String getCurrentSchemaCommand() { + return "call schema()"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java index cb5e403ca3..0b87752d65 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java @@ -582,4 +582,9 @@ public class Oracle8iDialect extends Dialect { public String getNotExpression( String expression ) { return "not (" + expression + ")"; } + + @Override + public String getCurrentSchemaCommand() { + return "select sys_context( 'userenv', 'current_schema' ) from dual"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/TemporarySchemaNameResolver.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/DefaultSchemaNameResolver.java similarity index 80% rename from hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/TemporarySchemaNameResolver.java rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/DefaultSchemaNameResolver.java index 287514d47e..31af134bbb 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/TemporarySchemaNameResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/DefaultSchemaNameResolver.java @@ -28,22 +28,22 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver; /** - * Temporary implementation that works for H2. + * Default implementation * * @author Steve Ebersole */ -public class TemporarySchemaNameResolver implements SchemaNameResolver { - public static final TemporarySchemaNameResolver INSTANCE = new TemporarySchemaNameResolver(); +public class DefaultSchemaNameResolver implements SchemaNameResolver { + public static final DefaultSchemaNameResolver INSTANCE = new DefaultSchemaNameResolver(); @Override - public String resolveSchemaName(Connection connection) throws SQLException { - // the H2 variant... + public String resolveSchemaName(Connection connection, Dialect dialect) throws SQLException { Statement statement = connection.createStatement(); try { - ResultSet resultSet = statement.executeQuery( "call schema()" ); + ResultSet resultSet = statement.executeQuery( dialect.getCurrentSchemaCommand() ); try { if ( ! resultSet.next() ) { return null; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java index b1ec2086b1..63405a7752 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java @@ -53,6 +53,7 @@ import org.hibernate.exception.internal.SQLStateConversionDelegate; import org.hibernate.exception.internal.StandardSQLExceptionConverter; import org.hibernate.exception.spi.SQLExceptionConverter; import org.hibernate.metamodel.spi.relational.Identifier; +import org.hibernate.service.ServiceRegistry; import org.hibernate.service.spi.ServiceRegistryImplementor; /** @@ -216,7 +217,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { } private Identifier determineCurrentSchema(DatabaseMetaData dbmd) throws SQLException { - String currentSchemaName = locateSchemaNameResolver().resolveSchemaName( dbmd.getConnection() ); + String currentSchemaName = locateSchemaNameResolver().resolveSchemaName( dbmd.getConnection(), dialect ); if ( currentSchemaName != null ) { // intentionally using fromMetaDataObjectName rather than fromMetaDataSchemaName !!! return identifierHelper.fromMetaDataObjectName( currentSchemaName ); @@ -235,7 +236,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { return serviceRegistry.getService( StrategySelector.class ).resolveDefaultableStrategy( SchemaNameResolver.class, setting, - TemporarySchemaNameResolver.INSTANCE + DefaultSchemaNameResolver.INSTANCE ); } @@ -301,4 +302,9 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { } return null; } + + @Override + public ServiceRegistry getServiceRegistry() { + return serviceRegistry; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/NormalizingIdentifierHelperImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/NormalizingIdentifierHelperImpl.java index 43a88fa1c5..7cde165750 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/NormalizingIdentifierHelperImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/NormalizingIdentifierHelperImpl.java @@ -95,7 +95,7 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper { public String toMetaDataCatalogName(Identifier identifier) { if ( identifier == null ) { // todo : not sure if this is interpreted as <""> or - return jdbcEnvironment.getCurrentCatalog().getText(); + return jdbcEnvironment.getCurrentCatalog() == null ? null : jdbcEnvironment.getCurrentCatalog().getText(); } return toText( identifier ); @@ -124,7 +124,7 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper { public String toMetaDataSchemaName(Identifier identifier) { if ( identifier == null ) { // todo : not sure if this is interpreted as <""> or - return jdbcEnvironment.getCurrentSchema().getText(); + return jdbcEnvironment.getCurrentSchema() == null ? null : jdbcEnvironment.getCurrentSchema().getText(); } return toText( identifier ); @@ -145,7 +145,8 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper { return null; } - if ( catalogName.equals( jdbcEnvironment.getCurrentCatalog().getText() ) ) { + if ( jdbcEnvironment.getCurrentCatalog() == null + || catalogName.equals( jdbcEnvironment.getCurrentCatalog().getText() ) ) { return null; } @@ -197,7 +198,8 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper { return null; } - if ( schemaName.equals( jdbcEnvironment.getCurrentSchema().getText() ) ) { + if ( jdbcEnvironment.getCurrentSchema() == null + || schemaName.equals( jdbcEnvironment.getCurrentSchema().getText() ) ) { return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/JdbcEnvironment.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/JdbcEnvironment.java index 8a51092567..a510f4be34 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/JdbcEnvironment.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/JdbcEnvironment.java @@ -30,6 +30,7 @@ import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; import org.hibernate.engine.jdbc.spi.TypeInfo; import org.hibernate.metamodel.spi.relational.Identifier; import org.hibernate.service.Service; +import org.hibernate.service.ServiceRegistry; /** * Initial look at this concept we keep talking about with merging information from {@link java.sql.DatabaseMetaData} @@ -118,4 +119,6 @@ public interface JdbcEnvironment extends Service { * @return The corresponding type info. */ public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode); + + public ServiceRegistry getServiceRegistry(); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/SchemaNameResolver.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/SchemaNameResolver.java index 7783143bfe..c9da81ee97 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/SchemaNameResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/spi/SchemaNameResolver.java @@ -26,6 +26,8 @@ package org.hibernate.engine.jdbc.env.spi; import java.sql.Connection; import java.sql.SQLException; +import org.hibernate.dialect.Dialect; + /** * Contract for resolving the schema of a {@link Connection}. * @@ -36,8 +38,9 @@ public interface SchemaNameResolver { * Given a JDBC {@link Connection}, resolve the name of the schema (if one) to which it connects. * * @param connection The JDBC connection + * @param dialect The Dialect * * @return The name of the schema (may be null). */ - public String resolveSchemaName(Connection connection) throws SQLException; + public String resolveSchemaName(Connection connection, Dialect dialect) throws SQLException; } diff --git a/hibernate-core/src/main/java/org/hibernate/id/factory/internal/DefaultIdentifierGeneratorFactory.java b/hibernate-core/src/main/java/org/hibernate/id/factory/internal/DefaultIdentifierGeneratorFactory.java index a3720eb461..7368f24a37 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/factory/internal/DefaultIdentifierGeneratorFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/id/factory/internal/DefaultIdentifierGeneratorFactory.java @@ -50,6 +50,7 @@ import org.hibernate.id.enhanced.SequenceStyleGenerator; import org.hibernate.id.enhanced.TableGenerator; import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory; import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ReflectHelper; import org.hibernate.service.spi.ServiceRegistryAwareService; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.type.Type; @@ -134,13 +135,22 @@ public class DefaultIdentifierGeneratorFactory implements MutableIdentifierGener Class generatorClass = generatorStrategyToClassNameMap.get( strategy ); try { if ( generatorClass == null ) { - generatorClass = classLoaderService.classForName( strategy ); + // TODO: Exists purely for testing using the old .mappings. Eventually remove. + if (classLoaderService == null) { + generatorClass = ReflectHelper.classForName( strategy ); + } + else { + generatorClass = classLoaderService.classForName( strategy ); + } register( strategy, generatorClass ); } } catch ( ClassLoadingException e ) { throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) ); } + catch ( ClassNotFoundException e ) { + throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) ); + } return generatorClass; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Column.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Column.java index 60b74979f4..bf6df8cdd4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Column.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Column.java @@ -85,13 +85,29 @@ public class Column extends AbstractValue { } public String getSqlType() { - return sqlType; + return sqlType; } public void setSqlType(String sqlType) { this.sqlType = sqlType; } + // TODO: Solely used by schema tools. Re-think this, getSqlType, and getJdbcDataType. Clean-up and/or + // condense somehow? + public String getSqlTypeString(Dialect dialect) { + if ( sqlType != null ) { + return sqlType; + } + else { + return dialect.getTypeName( + getJdbcDataType().getTypeCode(), + size.getLength(), + size.getPrecision(), + size.getScale() + ); + } + } + public String getReadFragment() { return readFragment; } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java b/hibernate-core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java old mode 100755 new mode 100644 index a93a918fcd..28c7277b3b --- a/hibernate-core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java @@ -26,6 +26,7 @@ package org.hibernate.tool.hbm2ddl; import java.io.FileInputStream; import java.sql.Connection; import java.sql.SQLException; +import java.util.Map; import java.util.Properties; import org.hibernate.HibernateException; @@ -36,10 +37,17 @@ import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.cfg.NamingStrategy; import org.hibernate.dialect.Dialect; +import org.hibernate.engine.config.spi.ConfigurationService; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.service.ServiceRegistry; +import org.hibernate.tool.schema.extract.spi.DatabaseInformation; +import org.hibernate.tool.schema.extract.spi.DatabaseInformationBuilder; +import org.hibernate.tool.schema.spi.SchemaManagementTool; import org.jboss.logging.Logger; /** @@ -47,18 +55,41 @@ import org.jboss.logging.Logger; * inside an application. * * @author Christoph Sturm + * @author Brett Meyer */ public class SchemaValidator { private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SchemaValidator.class.getName()); private ConnectionHelper connectionHelper; - private Configuration configuration; private Dialect dialect; + + private MetadataImplementor metadata; + // TODO: eventually remove + private Configuration configuration; + public SchemaValidator(MetadataImplementor metadata, Connection connection) { + this.metadata = metadata; + ServiceRegistry serviceRegistry = metadata.getServiceRegistry(); + if ( connection != null ) { + this.connectionHelper = new SuppliedConnectionHelper( connection ); + } + else { + this.connectionHelper = new SuppliedConnectionProviderConnectionHelper( + serviceRegistry.getService( ConnectionProvider.class ) + ); + } + } + + public SchemaValidator(MetadataImplementor metadata) { + this( metadata, null ); + } + + @Deprecated public SchemaValidator(Configuration cfg) throws HibernateException { this( cfg, cfg.getProperties() ); } + @Deprecated public SchemaValidator(Configuration cfg, Properties connectionProperties) throws HibernateException { this.configuration = cfg; dialect = Dialect.getDialect( connectionProperties ); @@ -68,6 +99,7 @@ public class SchemaValidator { connectionHelper = new ManagedProviderConnectionHelper( props ); } + @Deprecated public SchemaValidator(ServiceRegistry serviceRegistry, Configuration cfg ) throws HibernateException { this.configuration = cfg; final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); @@ -136,24 +168,36 @@ public class SchemaValidator { LOG.runningSchemaValidator(); - Connection connection = null; - try { + + connectionHelper.prepare( false ); + Connection connection = connectionHelper.getConnection(); + + if ( metadata != null ) { + final ServiceRegistry serviceRegistry = metadata.getServiceRegistry(); + final Map settings = serviceRegistry.getService( ConfigurationService.class ).getSettings(); - DatabaseMetadata meta; - try { - LOG.fetchingDatabaseMetadata(); - connectionHelper.prepare( false ); - connection = connectionHelper.getConnection(); - meta = new DatabaseMetadata( connection, dialect, configuration, false ); + final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcServices.class ) + .getJdbcEnvironment(); + final DatabaseInformation databaseInformation + = new DatabaseInformationBuilder( jdbcEnvironment, connection ).prepareAll().build(); + final SchemaManagementTool schemaManagementTool = serviceRegistry.getService( + SchemaManagementTool.class ); + schemaManagementTool.getSchemaValidator( settings ).doValidation( + metadata.getDatabase(), databaseInformation ); } - catch ( SQLException sqle ) { - LOG.unableToGetDatabaseMetadata(sqle); - throw sqle; + else { + DatabaseMetadata meta; + try { + LOG.fetchingDatabaseMetadata(); + meta = new DatabaseMetadata( connection, dialect, configuration, false ); + } + catch ( SQLException sqle ) { + LOG.unableToGetDatabaseMetadata(sqle); + throw sqle; + } + configuration.validateSchema( dialect, meta ); } - - configuration.validateSchema( dialect, meta ); - } catch ( SQLException e ) { LOG.unableToCompleteSchemaValidation(e); diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/StandardJdbcDatabaseMetaDataExtractor.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/StandardJdbcDatabaseMetaDataExtractor.java index c86725b497..2d9bb58aee 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/StandardJdbcDatabaseMetaDataExtractor.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/StandardJdbcDatabaseMetaDataExtractor.java @@ -34,8 +34,11 @@ import java.util.StringTokenizer; import org.hibernate.JDBCException; import org.hibernate.TruthValue; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.jdbc.env.spi.IdentifierHelper; import org.hibernate.internal.util.compare.EqualsHelper; +import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.metamodel.spi.relational.Identifier; import org.hibernate.metamodel.spi.relational.ObjectName; import org.hibernate.tool.schema.extract.spi.ColumnInformation; @@ -55,12 +58,21 @@ import org.hibernate.tool.schema.spi.SchemaManagementException; * @author Steve Ebersole */ public class StandardJdbcDatabaseMetaDataExtractor implements SchemaMetaDataExtractor { - private static final String[] TABLE_TYPES = new String[] { "TABLE", "VIEW" }; + private final String[] tableTypes; private final ExtractionContext extractionContext; public StandardJdbcDatabaseMetaDataExtractor(ExtractionContext extractionContext) { this.extractionContext = extractionContext; + + ConfigurationService configService = extractionContext.getJdbcEnvironment().getServiceRegistry() + .getService( ConfigurationService.class ); + if (ConfigurationHelper.getBoolean( AvailableSettings.ENABLE_SYNONYMS, configService.getSettings(), false ) ) { + tableTypes = new String[] { "TABLE", "VIEW", "SYNONYM" }; + } + else { + tableTypes = new String[] { "TABLE", "VIEW" }; + } } protected IdentifierHelper identifierHelper() { @@ -78,7 +90,7 @@ public class StandardJdbcDatabaseMetaDataExtractor implements SchemaMetaDataExtr catalogFilter, schemaFilter, null, - TABLE_TYPES + tableTypes ); final List results = new ArrayList(); diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformationBuilder.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformationBuilder.java index 4e924d39d5..c89f85f6f9 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformationBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformationBuilder.java @@ -26,6 +26,7 @@ package org.hibernate.tool.schema.extract.spi; import java.sql.Connection; import java.sql.SQLException; +import org.hibernate.dialect.H2Dialect; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.env.spi.IdentifierHelper; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; @@ -125,6 +126,11 @@ public class DatabaseInformationBuilder { } private Iterable extractSequences() { + if (!extractionContext.getJdbcEnvironment().getDialect().getClass().isAssignableFrom( H2Dialect.class )) { + // TODO: the temporary impl below is for H2 only + return null; + } + // todo : temporary impl!!! final TemporarySequenceInformationExtractor seqExtractor = new TemporarySequenceInformationExtractor(); try { diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/HibernateSchemaManagementTool.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/HibernateSchemaManagementTool.java index cb2c430528..fef39ec96c 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/HibernateSchemaManagementTool.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/HibernateSchemaManagementTool.java @@ -25,6 +25,11 @@ package org.hibernate.tool.schema.internal; import java.util.Map; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.service.ServiceRegistry; +import org.hibernate.service.spi.ServiceRegistryAwareService; +import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.tool.schema.spi.SchemaCreator; import org.hibernate.tool.schema.spi.SchemaDropper; import org.hibernate.tool.schema.spi.SchemaManagementTool; @@ -36,7 +41,10 @@ import org.hibernate.tool.schema.spi.SchemaValidator; * * @author Steve Ebersole */ -public class HibernateSchemaManagementTool implements SchemaManagementTool { +public class HibernateSchemaManagementTool implements SchemaManagementTool, ServiceRegistryAwareService { + + private ServiceRegistry serviceRegistry; + @Override public SchemaCreator getSchemaCreator(Map options) { return new SchemaCreatorImpl(); @@ -54,6 +62,12 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool { @Override public SchemaValidator getSchemaValidator(Map options) { - return new SchemaValidatorImpl(); + final Dialect dialect = serviceRegistry.getService( JdbcServices.class ).getDialect(); + return new SchemaValidatorImpl(dialect); + } + + @Override + public void injectServices(ServiceRegistryImplementor serviceRegistry) { + this.serviceRegistry = serviceRegistry; } } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java index 3ce633e10e..bb07edac6c 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java @@ -23,6 +23,7 @@ */ package org.hibernate.tool.schema.internal; +import org.hibernate.dialect.Dialect; import org.hibernate.metamodel.spi.relational.Column; import org.hibernate.metamodel.spi.relational.Database; import org.hibernate.metamodel.spi.relational.Schema; @@ -40,6 +41,13 @@ import org.hibernate.tool.schema.spi.SchemaValidator; * @author Steve Ebersole */ public class SchemaValidatorImpl implements SchemaValidator { + + private final Dialect dialect; + + public SchemaValidatorImpl(Dialect dialect) { + this.dialect = dialect; + } + @Override public void doValidation(Database database, DatabaseInformation databaseInformation) { for ( Schema schema : database.getSchemas() ) { @@ -96,7 +104,7 @@ public class SchemaValidatorImpl implements SchemaValidator { protected void validateColumnType(Table table, Column column, ColumnInformation columnInformation) { // this is the old Hibernate check... final boolean typesMatch = column.getJdbcDataType().getTypeCode() == columnInformation.getTypeCode() - || column.getSqlType().toLowerCase().startsWith( columnInformation.getTypeName().toLowerCase() ); + || column.getSqlTypeString(dialect).toLowerCase().startsWith( columnInformation.getTypeName().toLowerCase() ); if ( !typesMatch ) { throw new SchemaManagementException( String.format( diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java index a135b5e8c9..eeab57f2be 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java @@ -30,7 +30,6 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.metamodel.spi.relational.CheckConstraint; import org.hibernate.metamodel.spi.relational.Column; -import org.hibernate.metamodel.spi.relational.Size; import org.hibernate.metamodel.spi.relational.Table; import org.hibernate.tool.schema.spi.Exporter; @@ -81,13 +80,13 @@ public class StandardTableExporter implements Exporter { if ( isPrimaryKeyIdentity && colName.equals( pkColName ) ) { // to support dialects that have their own identity data type if ( dialect.hasDataTypeInIdentityColumn() ) { - buf.append( getTypeString( col, dialect ) ); + buf.append( col.getSqlTypeString( dialect ) ); } buf.append( ' ' ) .append( dialect.getIdentityColumnString( col.getJdbcDataType().getTypeCode() ) ); } else { - buf.append( getTypeString( col, dialect ) ); + buf.append( col.getSqlTypeString( dialect ) ); String defaultValue = col.getDefaultValue(); if ( defaultValue != null ) { @@ -165,26 +164,6 @@ public class StandardTableExporter implements Exporter
{ } - private static String getTypeString(Column col, Dialect dialect) { - String typeString; - if ( col.getSqlType() != null ) { - typeString = col.getSqlType(); - } - else { - Size size = col.getSize() == null ? - new Size( ) : - col.getSize(); - - typeString = dialect.getTypeName( - col.getJdbcDataType().getTypeCode(), - size.getLength(), - size.getPrecision(), - size.getScale() - ); - } - return typeString; - } - @Override public String[] getSqlDropStrings(Table table, JdbcEnvironment jdbcEnvironment) { StringBuilder buf = new StringBuilder( "drop table " ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/common/BasicTestingJdbcServiceImpl.java b/hibernate-core/src/test/java/org/hibernate/test/common/BasicTestingJdbcServiceImpl.java index 3047a053e5..e06fd4a248 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/common/BasicTestingJdbcServiceImpl.java +++ b/hibernate-core/src/test/java/org/hibernate/test/common/BasicTestingJdbcServiceImpl.java @@ -44,6 +44,7 @@ import org.hibernate.engine.jdbc.spi.ResultSetWrapper; import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.metamodel.spi.relational.Identifier; +import org.hibernate.service.ServiceRegistry; import org.hibernate.service.spi.Stoppable; import org.hibernate.testing.env.ConnectionProviderBuilder; @@ -172,5 +173,10 @@ public class BasicTestingJdbcServiceImpl implements JdbcServices { public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode) { return null; } + + @Override + public ServiceRegistry getServiceRegistry() { + return null; + } } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/schemavalidation/SynonymValidationTest.java b/hibernate-core/src/test/java/org/hibernate/test/schemavalidation/SynonymValidationTest.java index d540e90ad9..632282799c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/schemavalidation/SynonymValidationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/schemavalidation/SynonymValidationTest.java @@ -20,76 +20,82 @@ */ package org.hibernate.test.schemavalidation; -import java.io.Serializable; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; +import org.hibernate.Session; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.AvailableSettings; -import org.hibernate.cfg.Configuration; -import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.dialect.Oracle9iDialect; -import org.hibernate.testing.FailureExpectedWithNewMetamodel; +import org.hibernate.metamodel.MetadataSources; +import org.hibernate.metamodel.internal.MetadataBuilderImpl; +import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.testing.RequiresDialect; -import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.tool.hbm2ddl.SchemaValidator; import org.junit.Test; /** + * Allows the BaseCoreFunctionalTestCase to create the schema using TestEntity. The test method validates against an + * identical entity, but using the synonym name. + * * @author Brett Meyer */ @RequiresDialect( Oracle9iDialect.class ) -@FailureExpectedWithNewMetamodel -public class SynonymValidationTest extends BaseUnitTestCase { +public class SynonymValidationTest extends BaseCoreFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { TestEntity.class }; + } @Test public void testSynonymValidation() { - if(isMetadataUsed()){ - throw new NotYetImplementedException( "SchemaValidator is not yet support metamodel" ); + Session s = openSession(); + s.getTransaction().begin(); + s.createSQLQuery( "CREATE OR REPLACE SYNONYM TEST_SYNONYM FOR TEST_ENTITY" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + + try { + StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder(); + serviceRegistryBuilder.applySetting( AvailableSettings.ENABLE_SYNONYMS, "true" ); + MetadataSources sources = new MetadataSources(serviceRegistryBuilder.build()); + sources.addAnnotatedClass( TestEntityWithSynonym.class ); + MetadataImplementor metadata = (MetadataImplementor) new MetadataBuilderImpl(sources).build(); + + SchemaValidator schemaValidator = new SchemaValidator( metadata ); + schemaValidator.validate(); + +// Configuration cfg = new Configuration(); +// cfg.addAnnotatedClass( TestEntityWithSynonym.class ); +// cfg.setProperty( AvailableSettings.ENABLE_SYNONYMS, "true" ); +// +// SchemaValidator schemaValidator = new SchemaValidator( cfg ); +// schemaValidator.validate(); + } + finally { + s = openSession(); + s.getTransaction().begin(); + s.createSQLQuery( "DROP SYNONYM TEST_SYNONYM FORCE" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); } -// Session s = openSession(); -// s.getTransaction().begin(); -// s.createSQLQuery( "CREATE SYNONYM test_synonym FOR test_entity" ).executeUpdate(); -// s.getTransaction().commit(); -// s.close(); - - Configuration cfg = new Configuration(); -// cfg.addAnnotatedClass( TestEntityWithSynonym.class ); - cfg.addAnnotatedClass( TestEntity.class ); - cfg.setProperty( AvailableSettings.ENABLE_SYNONYMS, "true" ); - cfg.setProperty( "hibernate.connection.includeSynonyms", "true" ); - cfg.getProperties().put( "includeSynonyms", true ); - -// SchemaValidator schemaValidator = new SchemaValidator( serviceRegistry(), cfg ); - SchemaValidator schemaValidator = new SchemaValidator( cfg ); - schemaValidator.validate(); - -// s = openSession(); -// s.getTransaction().begin(); -// s.createSQLQuery( "DROP SYNONYM test_synonym FORCE" ).executeUpdate(); -// s.getTransaction().commit(); -// s.close(); } -// protected Class[] getAnnotatedClasses() { -// return new Class[] { TestEntity.class }; -// } - @Entity - @Table(name = "TEST_SYN") - private static class TestEntity implements Serializable { - - private static final long serialVersionUID = 1L; - + @Table(name = "TEST_ENTITY") + private static class TestEntity { @Id @GeneratedValue private Long id; @Column(nullable = false) private String key; + private String value; public Long getId() { @@ -117,77 +123,40 @@ public class SynonymValidationTest extends BaseUnitTestCase { } } -// @Entity -// @Table(name = "test_entity") -// private static class TestEntity { -// @Id -// @GeneratedValue -// private Long id; -// -// @Column(nullable = false) -// private String key; -// -// private String value; -// -// public Long getId() { -// return id; -// } -// -// public void setId(Long id) { -// this.id = id; -// } -// -// public String getKey() { -// return key; -// } -// -// public void setKey(String key) { -// this.key = key; -// } -// -// public String getValue() { -// return value; -// } -// -// public void setValue(String value) { -// this.value = value; -// } -// } -// -// @Entity -// @Table(name = "test_synonym") -// private static class TestEntityWithSynonym { -// @Id -// @GeneratedValue -// private Long id; -// -// @Column(nullable = false) -// private String key; -// -// private String value; -// -// public Long getId() { -// return id; -// } -// -// public void setId(Long id) { -// this.id = id; -// } -// -// public String getKey() { -// return key; -// } -// -// public void setKey(String key) { -// this.key = key; -// } -// -// public String getValue() { -// return value; -// } -// -// public void setValue(String value) { -// this.value = value; -// } -// } + @Entity + @Table(name = "TEST_SYNONYM") + private static class TestEntityWithSynonym { + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String key; + + private String value; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } }