HHH-10332 - Disambiguate missing table name

This commit is contained in:
Dominique Toupin 2015-11-25 08:57:51 -05:00 committed by Vlad Mihalcea
parent 58303884bd
commit 15c83ab61b
2 changed files with 368 additions and 3 deletions

View File

@ -129,7 +129,7 @@ public class SchemaValidatorImpl implements SchemaValidator {
throw new SchemaManagementException(
String.format(
"Schema-validation: missing table [%s]",
table.getName()
table.getQualifiedTableName().toString()
)
);
}
@ -148,7 +148,7 @@ public class SchemaValidatorImpl implements SchemaValidator {
String.format(
"Schema-validation: missing column [%s] in table [%s]",
column.getName(),
table.getName()
table.getQualifiedTableName()
)
);
}
@ -171,7 +171,7 @@ public class SchemaValidatorImpl implements SchemaValidator {
"Schema-validation: wrong column type encountered in column [%s] in " +
"table [%s]; found [%s (Types#%s)], but expecting [%s (Types#%s)]",
column.getName(),
table.getName(),
table.getQualifiedTableName(),
columnInformation.getTypeName().toLowerCase(Locale.ROOT),
JdbcTypeNameMapper.getTypeName( columnInformation.getTypeCode() ),
column.getSqlType().toLowerCase(Locale.ROOT),

View File

@ -0,0 +1,365 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.tool.schema;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl;
import org.hibernate.tool.schema.internal.HibernateSchemaManagementTool;
import org.hibernate.tool.schema.internal.SchemaCreatorImpl;
import org.hibernate.tool.schema.internal.SchemaDropperImpl;
import org.hibernate.tool.schema.internal.SchemaValidatorImpl;
import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase;
import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl;
import org.hibernate.tool.schema.spi.ExceptionHandler;
import org.hibernate.tool.schema.spi.ExecutionOptions;
import org.hibernate.tool.schema.spi.SchemaManagementException;
import org.hibernate.tool.schema.spi.SchemaManagementTool;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.boot.JdbcConnectionAccessImpl;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jboss.logging.Logger;
import static org.junit.Assert.assertEquals;
/**
* @author Dominique Toupin
*/
@TestForIssue(jiraKey = "HHH-10332")
@RequiresDialect(H2Dialect.class)
public class SchemaValidatorImplTest extends BaseUnitTestCase {
@Rule
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
Logger.getMessageLogger( CoreMessageLogger.class, SchemaValidatorImplTest.class.getName() ) );
private StandardServiceRegistry ssr;
private HibernateSchemaManagementTool tool;
private Map configurationValues;
private ExecutionOptions executionOptions;
@Before
public void setUp() throws IOException {
ssr = new StandardServiceRegistryBuilder().build();
tool = (HibernateSchemaManagementTool) ssr.getService( SchemaManagementTool.class );
configurationValues = ssr.getService( ConfigurationService.class ).getSettings();
executionOptions = new ExecutionOptions() {
@Override
public boolean shouldManageNamespaces() {
return true;
}
@Override
public Map getConfigurationValues() {
return configurationValues;
}
@Override
public ExceptionHandler getExceptionHandler() {
return ExceptionHandlerLoggedImpl.INSTANCE;
}
};
}
@After
public void tearsDown() {
StandardServiceRegistryBuilder.destroy( ssr );
}
@Test
public void testMissingEntityContainsQualifiedEntityName() throws Exception {
final MetadataSources metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( MissingEntity.class );
final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata();
metadata.validate();
try {
new SchemaValidatorImpl( tool ).doValidation( metadata, executionOptions );
Assert.fail( "SchemaManagementException expected" );
}
catch (SchemaManagementException e) {
assertEquals("Schema-validation: missing table [SomeCatalog.SomeSchema.MissingEntity]", e.getMessage());
}
}
@Test
public void testMissingEntityContainsUnqualifiedEntityName() throws Exception {
final MetadataSources metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( UnqualifiedMissingEntity.class );
final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata();
metadata.validate();
try {
new SchemaValidatorImpl( tool ).doValidation( metadata, executionOptions );
Assert.fail( "SchemaManagementException expected" );
}
catch (SchemaManagementException e) {
assertEquals("Schema-validation: missing table [UnqualifiedMissingEntity]", e.getMessage());
}
}
@Test
public void testMissingColumn() throws Exception {
MetadataSources metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( NoNameColumn.class );
MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata();
metadata.validate();
Map<String, Object> settings = new HashMap<>( );
ServiceRegistryImplementor serviceRegistry = (ServiceRegistryImplementor) new StandardServiceRegistryBuilder()
.applySettings( settings )
.build();
DriverManagerConnectionProviderImpl connectionProvider =
new DriverManagerConnectionProviderImpl();
connectionProvider.configure( properties() );
final GenerationTargetToDatabase schemaGenerator = new GenerationTargetToDatabase(
new JdbcConnectionContextNonSharedImpl(
new JdbcConnectionAccessImpl( connectionProvider ),
new SqlStatementLogger( false, true ),
true
)
);
try {
new SchemaCreatorImpl( ssr ).doCreation(
metadata,
serviceRegistry,
settings,
true,
schemaGenerator
);
metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( NameColumn.class );
metadata = (MetadataImplementor) metadataSources.buildMetadata();
metadata.validate();
try {
new SchemaValidatorImpl( tool ).doValidation( metadata, executionOptions );
Assert.fail( "SchemaManagementException expected" );
}
catch (SchemaManagementException e) {
assertEquals("Schema-validation: missing column [name] in table [SomeSchema.ColumnEntity]", e.getMessage());
}
}
finally {
new SchemaDropperImpl( serviceRegistry ).doDrop( metadata, false, schemaGenerator );
}
}
@Test
public void testMismatchColumnType() throws Exception {
MetadataSources metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( NameColumn.class );
MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata();
metadata.validate();
Map<String, Object> settings = new HashMap<>( );
ServiceRegistryImplementor serviceRegistry = (ServiceRegistryImplementor) new StandardServiceRegistryBuilder()
.applySettings( settings )
.build();
DriverManagerConnectionProviderImpl connectionProvider =
new DriverManagerConnectionProviderImpl();
connectionProvider.configure( properties() );
final GenerationTargetToDatabase schemaGenerator = new GenerationTargetToDatabase(
new JdbcConnectionContextNonSharedImpl(
new JdbcConnectionAccessImpl( connectionProvider ),
new SqlStatementLogger( false, true ),
true
)
);
try {
new SchemaCreatorImpl( ssr ).doCreation(
metadata,
serviceRegistry,
settings,
true,
schemaGenerator
);
metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( IntegerNameColumn.class );
metadata = (MetadataImplementor) metadataSources.buildMetadata();
metadata.validate();
try {
new SchemaValidatorImpl( tool ).doValidation( metadata, executionOptions );
Assert.fail( "SchemaManagementException expected" );
}
catch (SchemaManagementException e) {
assertEquals("Schema-validation: wrong column type encountered in column [name] in table [SomeSchema.ColumnEntity]; found [varchar (Types#VARCHAR)], but expecting [integer (Types#INTEGER)]", e.getMessage());
}
}
finally {
new SchemaDropperImpl( serviceRegistry ).doDrop( metadata, false, schemaGenerator );
}
}
protected Properties properties() {
Properties properties = new Properties( );
URL propertiesURL = Thread.currentThread().getContextClassLoader().getResource( "hibernate.properties" );
try(FileInputStream inputStream = new FileInputStream( propertiesURL.getFile() )) {
properties.load( inputStream );
}
catch (IOException e) {
throw new IllegalArgumentException( e );
}
return properties;
}
@Entity
@PrimaryKeyJoinColumn
@Table(name = "UnqualifiedMissingEntity")
public static class UnqualifiedMissingEntity {
private String id;
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
@Entity
@PrimaryKeyJoinColumn
@Table(name = "MissingEntity", catalog = "SomeCatalog", schema = "SomeSchema")
public static class MissingEntity {
private String id;
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
@Entity
@PrimaryKeyJoinColumn
@Table(name = "ColumnEntity", schema = "SomeSchema")
public static class NoNameColumn {
private String id;
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
@Entity
@PrimaryKeyJoinColumn
@Table(name = "ColumnEntity", schema = "SomeSchema")
public static class NameColumn {
private String id;
private String name;
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
@PrimaryKeyJoinColumn
@Table(name = "ColumnEntity", schema = "SomeSchema")
public static class IntegerNameColumn {
private String id;
private Integer name;
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getName() {
return name;
}
public void setName(Integer name) {
this.name = name;
}
}
}