HHH-6446 Integrate new metamodel into SchemaValidator

This commit is contained in:
Brett Meyer 2013-08-27 18:47:30 -04:00
parent f4ebc36adb
commit 479bc0bb5a
18 changed files with 269 additions and 172 deletions

View File

@ -2024,6 +2024,15 @@ public abstract class Dialect implements ConversionContext {
return "drop schema " + 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 <tt>ALTER TABLE</tt> syntax? * Does this dialect support the <tt>ALTER TABLE</tt> syntax?
* *

View File

@ -422,4 +422,9 @@ public class H2Dialect extends Dialect {
// see http://groups.google.com/group/h2-database/browse_thread/thread/562d8a49e2dabe99?hl=en // see http://groups.google.com/group/h2-database/browse_thread/thread/562d8a49e2dabe99?hl=en
return true; return true;
} }
@Override
public String getCurrentSchemaCommand() {
return "call schema()";
}
} }

View File

@ -582,4 +582,9 @@ public class Oracle8iDialect extends Dialect {
public String getNotExpression( String expression ) { public String getNotExpression( String expression ) {
return "not (" + expression + ")"; return "not (" + expression + ")";
} }
@Override
public String getCurrentSchemaCommand() {
return "select sys_context( 'userenv', 'current_schema' ) from dual";
}
} }

View File

@ -28,22 +28,22 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver; import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
/** /**
* Temporary implementation that works for H2. * Default implementation
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class TemporarySchemaNameResolver implements SchemaNameResolver { public class DefaultSchemaNameResolver implements SchemaNameResolver {
public static final TemporarySchemaNameResolver INSTANCE = new TemporarySchemaNameResolver(); public static final DefaultSchemaNameResolver INSTANCE = new DefaultSchemaNameResolver();
@Override @Override
public String resolveSchemaName(Connection connection) throws SQLException { public String resolveSchemaName(Connection connection, Dialect dialect) throws SQLException {
// the H2 variant...
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
try { try {
ResultSet resultSet = statement.executeQuery( "call schema()" ); ResultSet resultSet = statement.executeQuery( dialect.getCurrentSchemaCommand() );
try { try {
if ( ! resultSet.next() ) { if ( ! resultSet.next() ) {
return null; return null;

View File

@ -53,6 +53,7 @@ import org.hibernate.exception.internal.SQLStateConversionDelegate;
import org.hibernate.exception.internal.StandardSQLExceptionConverter; import org.hibernate.exception.internal.StandardSQLExceptionConverter;
import org.hibernate.exception.spi.SQLExceptionConverter; import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.metamodel.spi.relational.Identifier; import org.hibernate.metamodel.spi.relational.Identifier;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
/** /**
@ -216,7 +217,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
} }
private Identifier determineCurrentSchema(DatabaseMetaData dbmd) throws SQLException { private Identifier determineCurrentSchema(DatabaseMetaData dbmd) throws SQLException {
String currentSchemaName = locateSchemaNameResolver().resolveSchemaName( dbmd.getConnection() ); String currentSchemaName = locateSchemaNameResolver().resolveSchemaName( dbmd.getConnection(), dialect );
if ( currentSchemaName != null ) { if ( currentSchemaName != null ) {
// intentionally using fromMetaDataObjectName rather than fromMetaDataSchemaName !!! // intentionally using fromMetaDataObjectName rather than fromMetaDataSchemaName !!!
return identifierHelper.fromMetaDataObjectName( currentSchemaName ); return identifierHelper.fromMetaDataObjectName( currentSchemaName );
@ -235,7 +236,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
return serviceRegistry.getService( StrategySelector.class ).resolveDefaultableStrategy( return serviceRegistry.getService( StrategySelector.class ).resolveDefaultableStrategy(
SchemaNameResolver.class, SchemaNameResolver.class,
setting, setting,
TemporarySchemaNameResolver.INSTANCE DefaultSchemaNameResolver.INSTANCE
); );
} }
@ -301,4 +302,9 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
} }
return null; return null;
} }
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
} }

View File

@ -95,7 +95,7 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper {
public String toMetaDataCatalogName(Identifier identifier) { public String toMetaDataCatalogName(Identifier identifier) {
if ( identifier == null ) { if ( identifier == null ) {
// todo : not sure if this is interpreted as <""> or <currentCatalog> // todo : not sure if this is interpreted as <""> or <currentCatalog>
return jdbcEnvironment.getCurrentCatalog().getText(); return jdbcEnvironment.getCurrentCatalog() == null ? null : jdbcEnvironment.getCurrentCatalog().getText();
} }
return toText( identifier ); return toText( identifier );
@ -124,7 +124,7 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper {
public String toMetaDataSchemaName(Identifier identifier) { public String toMetaDataSchemaName(Identifier identifier) {
if ( identifier == null ) { if ( identifier == null ) {
// todo : not sure if this is interpreted as <""> or <currentSchema> // todo : not sure if this is interpreted as <""> or <currentSchema>
return jdbcEnvironment.getCurrentSchema().getText(); return jdbcEnvironment.getCurrentSchema() == null ? null : jdbcEnvironment.getCurrentSchema().getText();
} }
return toText( identifier ); return toText( identifier );
@ -145,7 +145,8 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper {
return null; return null;
} }
if ( catalogName.equals( jdbcEnvironment.getCurrentCatalog().getText() ) ) { if ( jdbcEnvironment.getCurrentCatalog() == null
|| catalogName.equals( jdbcEnvironment.getCurrentCatalog().getText() ) ) {
return null; return null;
} }
@ -197,7 +198,8 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper {
return null; return null;
} }
if ( schemaName.equals( jdbcEnvironment.getCurrentSchema().getText() ) ) { if ( jdbcEnvironment.getCurrentSchema() == null
|| schemaName.equals( jdbcEnvironment.getCurrentSchema().getText() ) ) {
return null; return null;
} }

View File

@ -30,6 +30,7 @@ import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.jdbc.spi.TypeInfo; import org.hibernate.engine.jdbc.spi.TypeInfo;
import org.hibernate.metamodel.spi.relational.Identifier; import org.hibernate.metamodel.spi.relational.Identifier;
import org.hibernate.service.Service; 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} * 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. * @return The corresponding type info.
*/ */
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode); public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode);
public ServiceRegistry getServiceRegistry();
} }

View File

@ -26,6 +26,8 @@ package org.hibernate.engine.jdbc.env.spi;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.dialect.Dialect;
/** /**
* Contract for resolving the schema of a {@link Connection}. * 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. * Given a JDBC {@link Connection}, resolve the name of the schema (if one) to which it connects.
* *
* @param connection The JDBC connection * @param connection The JDBC connection
* @param dialect The Dialect
* *
* @return The name of the schema (may be null). * @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;
} }

View File

@ -50,6 +50,7 @@ import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.id.enhanced.TableGenerator; import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory; import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.service.spi.ServiceRegistryAwareService; import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.type.Type; import org.hibernate.type.Type;
@ -134,13 +135,22 @@ public class DefaultIdentifierGeneratorFactory implements MutableIdentifierGener
Class generatorClass = generatorStrategyToClassNameMap.get( strategy ); Class generatorClass = generatorStrategyToClassNameMap.get( strategy );
try { try {
if ( generatorClass == null ) { 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 ); register( strategy, generatorClass );
} }
} }
catch ( ClassLoadingException e ) { catch ( ClassLoadingException e ) {
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) ); 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; return generatorClass;
} }

View File

@ -85,13 +85,29 @@ public class Column extends AbstractValue {
} }
public String getSqlType() { public String getSqlType() {
return sqlType; return sqlType;
} }
public void setSqlType(String sqlType) { public void setSqlType(String sqlType) {
this.sqlType = 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() { public String getReadFragment() {
return readFragment; return readFragment;
} }

View File

@ -26,6 +26,7 @@ package org.hibernate.tool.hbm2ddl;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
@ -36,10 +37,17 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.cfg.NamingStrategy; import org.hibernate.cfg.NamingStrategy;
import org.hibernate.dialect.Dialect; 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.engine.jdbc.spi.JdbcServices;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.metamodel.spi.MetadataImplementor;
import org.hibernate.service.ServiceRegistry; 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; import org.jboss.logging.Logger;
/** /**
@ -47,18 +55,41 @@ import org.jboss.logging.Logger;
* inside an application. * inside an application.
* *
* @author Christoph Sturm * @author Christoph Sturm
* @author Brett Meyer
*/ */
public class SchemaValidator { public class SchemaValidator {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SchemaValidator.class.getName()); private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SchemaValidator.class.getName());
private ConnectionHelper connectionHelper; private ConnectionHelper connectionHelper;
private Configuration configuration;
private Dialect dialect; 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 { public SchemaValidator(Configuration cfg) throws HibernateException {
this( cfg, cfg.getProperties() ); this( cfg, cfg.getProperties() );
} }
@Deprecated
public SchemaValidator(Configuration cfg, Properties connectionProperties) throws HibernateException { public SchemaValidator(Configuration cfg, Properties connectionProperties) throws HibernateException {
this.configuration = cfg; this.configuration = cfg;
dialect = Dialect.getDialect( connectionProperties ); dialect = Dialect.getDialect( connectionProperties );
@ -68,6 +99,7 @@ public class SchemaValidator {
connectionHelper = new ManagedProviderConnectionHelper( props ); connectionHelper = new ManagedProviderConnectionHelper( props );
} }
@Deprecated
public SchemaValidator(ServiceRegistry serviceRegistry, Configuration cfg ) throws HibernateException { public SchemaValidator(ServiceRegistry serviceRegistry, Configuration cfg ) throws HibernateException {
this.configuration = cfg; this.configuration = cfg;
final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
@ -136,24 +168,36 @@ public class SchemaValidator {
LOG.runningSchemaValidator(); LOG.runningSchemaValidator();
Connection connection = null;
try { try {
DatabaseMetadata meta; connectionHelper.prepare( false );
try { Connection connection = connectionHelper.getConnection();
LOG.fetchingDatabaseMetadata();
connectionHelper.prepare( false );
connection = connectionHelper.getConnection();
meta = new DatabaseMetadata( connection, dialect, configuration, false );
}
catch ( SQLException sqle ) {
LOG.unableToGetDatabaseMetadata(sqle);
throw sqle;
}
configuration.validateSchema( dialect, meta ); if ( metadata != null ) {
final ServiceRegistry serviceRegistry = metadata.getServiceRegistry();
final Map settings = serviceRegistry.getService( ConfigurationService.class ).getSettings();
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 );
}
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 );
}
} }
catch ( SQLException e ) { catch ( SQLException e ) {
LOG.unableToCompleteSchemaValidation(e); LOG.unableToCompleteSchemaValidation(e);

View File

@ -34,8 +34,11 @@ import java.util.StringTokenizer;
import org.hibernate.JDBCException; import org.hibernate.JDBCException;
import org.hibernate.TruthValue; 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.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.internal.util.compare.EqualsHelper; 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.Identifier;
import org.hibernate.metamodel.spi.relational.ObjectName; import org.hibernate.metamodel.spi.relational.ObjectName;
import org.hibernate.tool.schema.extract.spi.ColumnInformation; import org.hibernate.tool.schema.extract.spi.ColumnInformation;
@ -55,12 +58,21 @@ import org.hibernate.tool.schema.spi.SchemaManagementException;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class StandardJdbcDatabaseMetaDataExtractor implements SchemaMetaDataExtractor { public class StandardJdbcDatabaseMetaDataExtractor implements SchemaMetaDataExtractor {
private static final String[] TABLE_TYPES = new String[] { "TABLE", "VIEW" }; private final String[] tableTypes;
private final ExtractionContext extractionContext; private final ExtractionContext extractionContext;
public StandardJdbcDatabaseMetaDataExtractor(ExtractionContext extractionContext) { public StandardJdbcDatabaseMetaDataExtractor(ExtractionContext extractionContext) {
this.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() { protected IdentifierHelper identifierHelper() {
@ -78,7 +90,7 @@ public class StandardJdbcDatabaseMetaDataExtractor implements SchemaMetaDataExtr
catalogFilter, catalogFilter,
schemaFilter, schemaFilter,
null, null,
TABLE_TYPES tableTypes
); );
final List<TableInformation> results = new ArrayList<TableInformation>(); final List<TableInformation> results = new ArrayList<TableInformation>();

View File

@ -26,6 +26,7 @@ package org.hibernate.tool.schema.extract.spi;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper; import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
@ -125,6 +126,11 @@ public class DatabaseInformationBuilder {
} }
private Iterable<SequenceInformation> extractSequences() { private Iterable<SequenceInformation> extractSequences() {
if (!extractionContext.getJdbcEnvironment().getDialect().getClass().isAssignableFrom( H2Dialect.class )) {
// TODO: the temporary impl below is for H2 only
return null;
}
// todo : temporary impl!!! // todo : temporary impl!!!
final TemporarySequenceInformationExtractor seqExtractor = new TemporarySequenceInformationExtractor(); final TemporarySequenceInformationExtractor seqExtractor = new TemporarySequenceInformationExtractor();
try { try {

View File

@ -25,6 +25,11 @@ package org.hibernate.tool.schema.internal;
import java.util.Map; 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.SchemaCreator;
import org.hibernate.tool.schema.spi.SchemaDropper; import org.hibernate.tool.schema.spi.SchemaDropper;
import org.hibernate.tool.schema.spi.SchemaManagementTool; import org.hibernate.tool.schema.spi.SchemaManagementTool;
@ -36,7 +41,10 @@ import org.hibernate.tool.schema.spi.SchemaValidator;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class HibernateSchemaManagementTool implements SchemaManagementTool { public class HibernateSchemaManagementTool implements SchemaManagementTool, ServiceRegistryAwareService {
private ServiceRegistry serviceRegistry;
@Override @Override
public SchemaCreator getSchemaCreator(Map options) { public SchemaCreator getSchemaCreator(Map options) {
return new SchemaCreatorImpl(); return new SchemaCreatorImpl();
@ -54,6 +62,12 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool {
@Override @Override
public SchemaValidator getSchemaValidator(Map options) { 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;
} }
} }

View File

@ -23,6 +23,7 @@
*/ */
package org.hibernate.tool.schema.internal; package org.hibernate.tool.schema.internal;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.spi.relational.Column; import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.Database; import org.hibernate.metamodel.spi.relational.Database;
import org.hibernate.metamodel.spi.relational.Schema; import org.hibernate.metamodel.spi.relational.Schema;
@ -40,6 +41,13 @@ import org.hibernate.tool.schema.spi.SchemaValidator;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class SchemaValidatorImpl implements SchemaValidator { public class SchemaValidatorImpl implements SchemaValidator {
private final Dialect dialect;
public SchemaValidatorImpl(Dialect dialect) {
this.dialect = dialect;
}
@Override @Override
public void doValidation(Database database, DatabaseInformation databaseInformation) { public void doValidation(Database database, DatabaseInformation databaseInformation) {
for ( Schema schema : database.getSchemas() ) { for ( Schema schema : database.getSchemas() ) {
@ -96,7 +104,7 @@ public class SchemaValidatorImpl implements SchemaValidator {
protected void validateColumnType(Table table, Column column, ColumnInformation columnInformation) { protected void validateColumnType(Table table, Column column, ColumnInformation columnInformation) {
// this is the old Hibernate check... // this is the old Hibernate check...
final boolean typesMatch = column.getJdbcDataType().getTypeCode() == columnInformation.getTypeCode() 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 ) { if ( !typesMatch ) {
throw new SchemaManagementException( throw new SchemaManagementException(
String.format( String.format(

View File

@ -30,7 +30,6 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.metamodel.spi.relational.CheckConstraint; import org.hibernate.metamodel.spi.relational.CheckConstraint;
import org.hibernate.metamodel.spi.relational.Column; import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.Size;
import org.hibernate.metamodel.spi.relational.Table; import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.tool.schema.spi.Exporter; import org.hibernate.tool.schema.spi.Exporter;
@ -81,13 +80,13 @@ public class StandardTableExporter implements Exporter<Table> {
if ( isPrimaryKeyIdentity && colName.equals( pkColName ) ) { if ( isPrimaryKeyIdentity && colName.equals( pkColName ) ) {
// to support dialects that have their own identity data type // to support dialects that have their own identity data type
if ( dialect.hasDataTypeInIdentityColumn() ) { if ( dialect.hasDataTypeInIdentityColumn() ) {
buf.append( getTypeString( col, dialect ) ); buf.append( col.getSqlTypeString( dialect ) );
} }
buf.append( ' ' ) buf.append( ' ' )
.append( dialect.getIdentityColumnString( col.getJdbcDataType().getTypeCode() ) ); .append( dialect.getIdentityColumnString( col.getJdbcDataType().getTypeCode() ) );
} }
else { else {
buf.append( getTypeString( col, dialect ) ); buf.append( col.getSqlTypeString( dialect ) );
String defaultValue = col.getDefaultValue(); String defaultValue = col.getDefaultValue();
if ( defaultValue != null ) { if ( defaultValue != null ) {
@ -165,26 +164,6 @@ public class StandardTableExporter implements Exporter<Table> {
} }
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 @Override
public String[] getSqlDropStrings(Table table, JdbcEnvironment jdbcEnvironment) { public String[] getSqlDropStrings(Table table, JdbcEnvironment jdbcEnvironment) {
StringBuilder buf = new StringBuilder( "drop table " ); StringBuilder buf = new StringBuilder( "drop table " );

View File

@ -44,6 +44,7 @@ import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.metamodel.spi.relational.Identifier; import org.hibernate.metamodel.spi.relational.Identifier;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.Stoppable; import org.hibernate.service.spi.Stoppable;
import org.hibernate.testing.env.ConnectionProviderBuilder; import org.hibernate.testing.env.ConnectionProviderBuilder;
@ -172,5 +173,10 @@ public class BasicTestingJdbcServiceImpl implements JdbcServices {
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode) { public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode) {
return null; return null;
} }
@Override
public ServiceRegistry getServiceRegistry() {
return null;
}
} }
} }

View File

@ -20,76 +20,82 @@
*/ */
package org.hibernate.test.schemavalidation; package org.hibernate.test.schemavalidation;
import java.io.Serializable;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import org.hibernate.Session;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.dialect.Oracle9iDialect; 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.RequiresDialect;
import org.hibernate.testing.junit4.BaseUnitTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.tool.hbm2ddl.SchemaValidator; import org.hibernate.tool.hbm2ddl.SchemaValidator;
import org.junit.Test; 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 * @author Brett Meyer
*/ */
@RequiresDialect( Oracle9iDialect.class ) @RequiresDialect( Oracle9iDialect.class )
@FailureExpectedWithNewMetamodel public class SynonymValidationTest extends BaseCoreFunctionalTestCase {
public class SynonymValidationTest extends BaseUnitTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { TestEntity.class };
}
@Test @Test
public void testSynonymValidation() { public void testSynonymValidation() {
if(isMetadataUsed()){ Session s = openSession();
throw new NotYetImplementedException( "SchemaValidator is not yet support metamodel" ); 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 @Entity
@Table(name = "TEST_SYN") @Table(name = "TEST_ENTITY")
private static class TestEntity implements Serializable { private static class TestEntity {
private static final long serialVersionUID = 1L;
@Id @Id
@GeneratedValue @GeneratedValue
private Long id; private Long id;
@Column(nullable = false) @Column(nullable = false)
private String key; private String key;
private String value; private String value;
public Long getId() { public Long getId() {
@ -117,77 +123,40 @@ public class SynonymValidationTest extends BaseUnitTestCase {
} }
} }
// @Entity @Entity
// @Table(name = "test_entity") @Table(name = "TEST_SYNONYM")
// private static class TestEntity { private static class TestEntityWithSynonym {
// @Id @Id
// @GeneratedValue @GeneratedValue
// private Long id; private Long id;
//
// @Column(nullable = false) @Column(nullable = false)
// private String key; private String key;
//
// private String value; private String value;
//
// public Long getId() { public Long getId() {
// return id; return id;
// } }
//
// public void setId(Long id) { public void setId(Long id) {
// this.id = id; this.id = id;
// } }
//
// public String getKey() { public String getKey() {
// return key; return key;
// } }
//
// public void setKey(String key) { public void setKey(String key) {
// this.key = key; this.key = key;
// } }
//
// public String getValue() { public String getValue() {
// return value; return value;
// } }
//
// public void setValue(String value) { public void setValue(String value) {
// this.value = 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;
// }
// }
} }