HHH-10332 - Disambiguate missing table name
(cherry picked from commit 15c83ab61b
)
This commit is contained in:
parent
824bbca677
commit
92b0fd6468
|
@ -129,7 +129,7 @@ public class SchemaValidatorImpl implements SchemaValidator {
|
||||||
throw new SchemaManagementException(
|
throw new SchemaManagementException(
|
||||||
String.format(
|
String.format(
|
||||||
"Schema-validation: missing table [%s]",
|
"Schema-validation: missing table [%s]",
|
||||||
table.getName()
|
table.getQualifiedTableName().toString()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ public class SchemaValidatorImpl implements SchemaValidator {
|
||||||
String.format(
|
String.format(
|
||||||
"Schema-validation: missing column [%s] in table [%s]",
|
"Schema-validation: missing column [%s] in table [%s]",
|
||||||
column.getName(),
|
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 " +
|
"Schema-validation: wrong column type encountered in column [%s] in " +
|
||||||
"table [%s]; found [%s (Types#%s)], but expecting [%s (Types#%s)]",
|
"table [%s]; found [%s (Types#%s)], but expecting [%s (Types#%s)]",
|
||||||
column.getName(),
|
column.getName(),
|
||||||
table.getName(),
|
table.getQualifiedTableName(),
|
||||||
columnInformation.getTypeName().toLowerCase(Locale.ROOT),
|
columnInformation.getTypeName().toLowerCase(Locale.ROOT),
|
||||||
JdbcTypeNameMapper.getTypeName( columnInformation.getTypeCode() ),
|
JdbcTypeNameMapper.getTypeName( columnInformation.getTypeCode() ),
|
||||||
column.getSqlType().toLowerCase(Locale.ROOT),
|
column.getSqlType().toLowerCase(Locale.ROOT),
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue