HHH-9788 - Schema generation re-triggered where it should not be

This commit is contained in:
Steve Ebersole 2015-05-15 13:46:58 -05:00
parent a50e5f3623
commit 2827a59f2d
4 changed files with 191 additions and 35 deletions

View File

@ -268,7 +268,7 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper {
// return null; // return null;
// } // }
return toIdentifier( schemaName ); return toIdentifierFromMetaData( schemaName );
} }
@Override @Override
@ -277,6 +277,6 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper {
return null; return null;
} }
return toIdentifier( objectName ); return toIdentifierFromMetaData( objectName );
} }
} }

View File

@ -42,10 +42,13 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.Mapping;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.tool.hbm2ddl.ColumnMetadata; import org.hibernate.tool.hbm2ddl.ColumnMetadata;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.hbm2ddl.TableMetadata; import org.hibernate.tool.hbm2ddl.TableMetadata;
import org.hibernate.tool.schema.extract.spi.ColumnInformation; import org.hibernate.tool.schema.extract.spi.ColumnInformation;
import org.hibernate.tool.schema.extract.spi.TableInformation; import org.hibernate.tool.schema.extract.spi.TableInformation;
import org.jboss.logging.Logger;
/** /**
* A relational table * A relational table
* *
@ -53,7 +56,6 @@ import org.hibernate.tool.schema.extract.spi.TableInformation;
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class Table implements RelationalModel, Serializable, Exportable { public class Table implements RelationalModel, Serializable, Exportable {
private Identifier catalog; private Identifier catalog;
private Identifier schema; private Identifier schema;
private Identifier name; private Identifier name;
@ -441,7 +443,7 @@ public class Table implements RelationalModel, Serializable, Exportable {
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
final Column column = (Column) iter.next(); final Column column = (Column) iter.next();
final ColumnInformation columnInfo = tableInfo.getColumn( Identifier.toIdentifier( column.getName() ) ); final ColumnInformation columnInfo = tableInfo.getColumn( Identifier.toIdentifier( column.getName(), column.isQuoted() ) );
if ( columnInfo == null ) { if ( columnInfo == null ) {
// the column doesnt exist at all. // the column doesnt exist at all.
@ -489,6 +491,10 @@ public class Table implements RelationalModel, Serializable, Exportable {
} }
if ( results.isEmpty() ) {
Logger.getLogger( SchemaUpdate.class ).debugf( "No alter strings for table : %s", getQuotedName() );
}
return results.iterator(); return results.iterator();
} }

View File

@ -37,7 +37,6 @@ import org.hibernate.JDBCException;
import org.hibernate.boot.model.TruthValue; import org.hibernate.boot.model.TruthValue;
import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.QualifiedTableName; import org.hibernate.boot.model.relational.QualifiedTableName;
import org.hibernate.boot.model.relational.Schema;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper; import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
@ -140,7 +139,12 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
); );
try { try {
while ( resultSet.next() ) { while ( resultSet.next() ) {
final TableInformation tableInformation = extractTableInformation( resultSet ); final TableInformation tableInformation = extractTableInformation(
catalog,
schema,
null,
resultSet
);
results.add( tableInformation ); results.add( tableInformation );
} }
} }
@ -177,20 +181,23 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
return extractionContext.getJdbcEnvironment().getIdentifierHelper().toMetaDataSchemaName( identifierToUse ); return extractionContext.getJdbcEnvironment().getIdentifierHelper().toMetaDataSchemaName( identifierToUse );
} }
public TableInformation extractTableInformation(ResultSet resultSet) throws SQLException { public TableInformation extractTableInformation(
final Identifier catalogIdentifier = identifierHelper().fromMetaDataCatalogName( Identifier catalog,
resultSet.getString( "TABLE_CAT" ) Identifier schema,
); Identifier name,
final Identifier schemaIdentifier = identifierHelper().fromMetaDataSchemaName( ResultSet resultSet) throws SQLException {
resultSet.getString( "TABLE_SCHEM" ) if ( catalog == null ) {
); catalog = identifierHelper().fromMetaDataCatalogName( resultSet.getString( "TABLE_CAT" ) );
final Identifier tableIdentifier = identifierHelper().fromMetaDataObjectName( }
resultSet.getString( "TABLE_NAME" ) if ( schema == null ) {
); schema = identifierHelper().fromMetaDataSchemaName( resultSet.getString( "TABLE_SCHEM" ) );
final QualifiedTableName tableName = new QualifiedTableName( }
new Schema.Name( catalogIdentifier, schemaIdentifier ), if ( name == null ) {
tableIdentifier name = identifierHelper().fromMetaDataObjectName( resultSet.getString( "TABLE_NAME" ) );
); }
final QualifiedTableName tableName = new QualifiedTableName( catalog, schema, name );
return new TableInformationImpl( return new TableInformationImpl(
this, this,
tableName, tableName,
@ -218,7 +225,12 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
return null; return null;
} }
final TableInformation tableInformation = extractTableInformation( resultSet ); final TableInformation tableInformation = extractTableInformation(
catalog,
schema,
tableName,
resultSet
);
if ( resultSet.next() ) { if ( resultSet.next() ) {
log.multipleTablesFound( tableName.render() ); log.multipleTablesFound( tableName.render() );
@ -265,7 +277,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
results.add( results.add(
new ColumnInformationImpl( new ColumnInformationImpl(
tableInformation, tableInformation,
Identifier.toIdentifier( columnName ), identifierHelper().fromMetaDataObjectName( columnName ),
resultSet.getInt( "DATA_TYPE" ), resultSet.getInt( "DATA_TYPE" ),
new StringTokenizer( resultSet.getString( "TYPE_NAME" ), "() " ).nextToken(), new StringTokenizer( resultSet.getString( "TYPE_NAME" ), "() " ).nextToken(),
resultSet.getInt( "COLUMN_SIZE" ), resultSet.getInt( "COLUMN_SIZE" ),
@ -382,14 +394,18 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
continue; continue;
} }
final Identifier indexIdentifier = Identifier.toIdentifier( resultSet.getString( "INDEX_NAME" ) ); final Identifier indexIdentifier = identifierHelper().fromMetaDataObjectName(
resultSet.getString(
"INDEX_NAME"
)
);
IndexInformationImpl.Builder builder = builders.get( indexIdentifier ); IndexInformationImpl.Builder builder = builders.get( indexIdentifier );
if ( builder == null ) { if ( builder == null ) {
builder = IndexInformationImpl.builder( indexIdentifier ); builder = IndexInformationImpl.builder( indexIdentifier );
builders.put( indexIdentifier, builder ); builders.put( indexIdentifier, builder );
} }
final Identifier columnIdentifier = Identifier.toIdentifier( resultSet.getString( "COLUMN_NAME" ) ); final Identifier columnIdentifier = identifierHelper().fromMetaDataObjectName( resultSet.getString( "COLUMN_NAME" ) );
final ColumnInformation columnInformation = tableInformation.getColumn( columnIdentifier ); final ColumnInformation columnInformation = tableInformation.getColumn( columnIdentifier );
if ( columnInformation == null ) { if ( columnInformation == null ) {
throw new SchemaManagementException( throw new SchemaManagementException(
@ -434,7 +450,9 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
try { try {
while ( resultSet.next() ) { while ( resultSet.next() ) {
// IMPL NOTE : The builder is mainly used to collect the column reference mappings // IMPL NOTE : The builder is mainly used to collect the column reference mappings
final Identifier fkIdentifier = Identifier.toIdentifier( resultSet.getString( "FK_NAME" ) ); final Identifier fkIdentifier = identifierHelper().fromMetaDataObjectName(
resultSet.getString( "FK_NAME" )
);
ForeignKeyBuilder fkBuilder = fkBuilders.get( fkIdentifier ); ForeignKeyBuilder fkBuilder = fkBuilders.get( fkIdentifier );
if ( fkBuilder == null ) { if ( fkBuilder == null ) {
fkBuilder = generateForeignKeyBuilder( fkIdentifier ); fkBuilder = generateForeignKeyBuilder( fkIdentifier );
@ -454,8 +472,12 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
continue; continue;
} }
final Identifier fkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "FKCOLUMN_NAME" ) ); final Identifier fkColumnIdentifier = identifierHelper().fromMetaDataObjectName(
final Identifier pkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "PKCOLUMN_NAME" ) ); resultSet.getString( "FKCOLUMN_NAME" )
);
final Identifier pkColumnIdentifier = identifierHelper().fromMetaDataObjectName(
resultSet.getString( "PKCOLUMN_NAME" )
);
fkBuilder.addColumnMapping( fkBuilder.addColumnMapping(
tableInformation.getColumn( fkColumnIdentifier ), tableInformation.getColumn( fkColumnIdentifier ),
@ -486,10 +508,10 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
return new ForeignKeyBuilderImpl( fkIdentifier ); return new ForeignKeyBuilderImpl( fkIdentifier );
} }
protected static interface ForeignKeyBuilder { protected interface ForeignKeyBuilder {
public ForeignKeyBuilder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced); ForeignKeyBuilder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced);
public ForeignKeyInformation build(); ForeignKeyInformation build();
} }
protected static class ForeignKeyBuilderImpl implements ForeignKeyBuilder { protected static class ForeignKeyBuilderImpl implements ForeignKeyBuilder {
@ -524,11 +546,9 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
final String incomingTableName = resultSet.getString( prefix + "TABLE_NAME" ); final String incomingTableName = resultSet.getString( prefix + "TABLE_NAME" );
return new QualifiedTableName( return new QualifiedTableName(
new Schema.Name( identifierHelper().fromMetaDataCatalogName( incomingCatalogName ),
Identifier.toIdentifier( incomingCatalogName ), identifierHelper().fromMetaDataSchemaName( incomingSchemaName ),
Identifier.toIdentifier( incomingSchemaName ) identifierHelper().fromMetaDataObjectName( incomingTableName )
),
Identifier.toIdentifier( incomingTableName )
); );
} }
} }

View File

@ -0,0 +1,130 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.schemaupdate;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* @author Steve Ebersole
*/
public class TestFkUpdating {
protected ServiceRegistry serviceRegistry;
protected MetadataImplementor metadata;
@Before
public void setUp() {
serviceRegistry = new StandardServiceRegistryBuilder().build();
metadata = (MetadataImplementor) new MetadataSources( serviceRegistry )
.addAnnotatedClass( User.class )
.addAnnotatedClass(Role.class)
.buildMetadata();
System.out.println( "********* Starting SchemaExport for START-UP *************************" );
SchemaExport schemaExport = new SchemaExport( serviceRegistry, metadata );
schemaExport.create( true, true );
System.out.println( "********* Completed SchemaExport for START-UP *************************" );
}
@After
public void tearDown() {
System.out.println( "********* Starting SchemaExport (drop) for TEAR-DOWN *************************" );
SchemaExport schemaExport = new SchemaExport( serviceRegistry, metadata );
schemaExport.drop( true, true );
System.out.println( "********* Completed SchemaExport (drop) for TEAR-DOWN *************************" );
StandardServiceRegistryBuilder.destroy( serviceRegistry );
serviceRegistry = null;
}
@Test
public void testUpdate() {
System.out.println( "********* Starting SchemaUpdate for TEST *************************" );
SchemaUpdate schemaUpdate = new SchemaUpdate( serviceRegistry, metadata );
schemaUpdate.execute( true, true );
System.out.println( "********* Completed SchemaUpdate for TEST *************************" );
}
@Entity( name = "User" )
@Table( name = "user" )
public static class User {
private Integer id;
private Set<Role> roles;
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment",strategy = "increment")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToMany
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
@Entity( name = "Role" )
@Table( name = "role" )
public class Role {
private Integer id;
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment",strategy = "increment")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
}