From 2827a59f2dd07b24c49472ce5a02dc9e57d1ef53 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 15 May 2015 13:46:58 -0500 Subject: [PATCH] HHH-9788 - Schema generation re-triggered where it should not be --- .../NormalizingIdentifierHelperImpl.java | 4 +- .../java/org/hibernate/mapping/Table.java | 10 +- ...tionExtractorJdbcDatabaseMetaDataImpl.java | 82 ++++++----- .../test/schemaupdate/TestFkUpdating.java | 130 ++++++++++++++++++ 4 files changed, 191 insertions(+), 35 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/schemaupdate/TestFkUpdating.java 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 ea1f8cfe57b8..98cd19189e9c 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 @@ -268,7 +268,7 @@ public Identifier fromMetaDataSchemaName(String schemaName) { // return null; // } - return toIdentifier( schemaName ); + return toIdentifierFromMetaData( schemaName ); } @Override @@ -277,6 +277,6 @@ public Identifier fromMetaDataObjectName(String objectName) { return null; } - return toIdentifier( objectName ); + return toIdentifierFromMetaData( objectName ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java index 39805afd8831..d6cbe3b290cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java @@ -42,10 +42,13 @@ import org.hibernate.engine.spi.Mapping; import org.hibernate.internal.util.StringHelper; import org.hibernate.tool.hbm2ddl.ColumnMetadata; +import org.hibernate.tool.hbm2ddl.SchemaUpdate; import org.hibernate.tool.hbm2ddl.TableMetadata; import org.hibernate.tool.schema.extract.spi.ColumnInformation; import org.hibernate.tool.schema.extract.spi.TableInformation; +import org.jboss.logging.Logger; + /** * A relational table * @@ -53,7 +56,6 @@ */ @SuppressWarnings("unchecked") public class Table implements RelationalModel, Serializable, Exportable { - private Identifier catalog; private Identifier schema; private Identifier name; @@ -441,7 +443,7 @@ public Iterator sqlAlterStrings( while ( iter.hasNext() ) { 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 ) { // the column doesnt exist at all. @@ -489,6 +491,10 @@ public Iterator sqlAlterStrings( } + if ( results.isEmpty() ) { + Logger.getLogger( SchemaUpdate.class ).debugf( "No alter strings for table : %s", getQuotedName() ); + } + return results.iterator(); } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java index dbe5955a40bf..fbe33b28596a 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java @@ -37,7 +37,6 @@ import org.hibernate.boot.model.TruthValue; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.relational.QualifiedTableName; -import org.hibernate.boot.model.relational.Schema; import org.hibernate.cfg.AvailableSettings; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.jdbc.env.spi.IdentifierHelper; @@ -140,7 +139,12 @@ public Collection getTables(Identifier catalog, Identifier sch ); try { while ( resultSet.next() ) { - final TableInformation tableInformation = extractTableInformation( resultSet ); + final TableInformation tableInformation = extractTableInformation( + catalog, + schema, + null, + resultSet + ); results.add( tableInformation ); } } @@ -177,20 +181,23 @@ private String determineSchemaFilter(Identifier schema) throws SQLException { return extractionContext.getJdbcEnvironment().getIdentifierHelper().toMetaDataSchemaName( identifierToUse ); } - public TableInformation extractTableInformation(ResultSet resultSet) throws SQLException { - final Identifier catalogIdentifier = identifierHelper().fromMetaDataCatalogName( - resultSet.getString( "TABLE_CAT" ) - ); - final Identifier schemaIdentifier = identifierHelper().fromMetaDataSchemaName( - resultSet.getString( "TABLE_SCHEM" ) - ); - final Identifier tableIdentifier = identifierHelper().fromMetaDataObjectName( - resultSet.getString( "TABLE_NAME" ) - ); - final QualifiedTableName tableName = new QualifiedTableName( - new Schema.Name( catalogIdentifier, schemaIdentifier ), - tableIdentifier - ); + public TableInformation extractTableInformation( + Identifier catalog, + Identifier schema, + Identifier name, + ResultSet resultSet) throws SQLException { + if ( catalog == null ) { + catalog = identifierHelper().fromMetaDataCatalogName( resultSet.getString( "TABLE_CAT" ) ); + } + if ( schema == null ) { + schema = identifierHelper().fromMetaDataSchemaName( resultSet.getString( "TABLE_SCHEM" ) ); + } + if ( name == null ) { + name = identifierHelper().fromMetaDataObjectName( resultSet.getString( "TABLE_NAME" ) ); + } + + final QualifiedTableName tableName = new QualifiedTableName( catalog, schema, name ); + return new TableInformationImpl( this, tableName, @@ -218,7 +225,12 @@ public TableInformation getTable(Identifier catalog, Identifier schema, Identifi return null; } - final TableInformation tableInformation = extractTableInformation( resultSet ); + final TableInformation tableInformation = extractTableInformation( + catalog, + schema, + tableName, + resultSet + ); if ( resultSet.next() ) { log.multipleTablesFound( tableName.render() ); @@ -265,7 +277,7 @@ public Iterable getColumns(TableInformation tableInformation) results.add( new ColumnInformationImpl( tableInformation, - Identifier.toIdentifier( columnName ), + identifierHelper().fromMetaDataObjectName( columnName ), resultSet.getInt( "DATA_TYPE" ), new StringTokenizer( resultSet.getString( "TYPE_NAME" ), "() " ).nextToken(), resultSet.getInt( "COLUMN_SIZE" ), @@ -382,14 +394,18 @@ public Iterable getIndexes(TableInformation tableInformation) 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 ); if ( builder == null ) { builder = IndexInformationImpl.builder( indexIdentifier ); 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 ); if ( columnInformation == null ) { throw new SchemaManagementException( @@ -434,7 +450,9 @@ public Iterable getForeignKeys(TableInformation tableInfo try { while ( resultSet.next() ) { // 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 ); if ( fkBuilder == null ) { fkBuilder = generateForeignKeyBuilder( fkIdentifier ); @@ -454,8 +472,12 @@ public Iterable getForeignKeys(TableInformation tableInfo continue; } - final Identifier fkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "FKCOLUMN_NAME" ) ); - final Identifier pkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "PKCOLUMN_NAME" ) ); + final Identifier fkColumnIdentifier = identifierHelper().fromMetaDataObjectName( + resultSet.getString( "FKCOLUMN_NAME" ) + ); + final Identifier pkColumnIdentifier = identifierHelper().fromMetaDataObjectName( + resultSet.getString( "PKCOLUMN_NAME" ) + ); fkBuilder.addColumnMapping( tableInformation.getColumn( fkColumnIdentifier ), @@ -486,10 +508,10 @@ private ForeignKeyBuilder generateForeignKeyBuilder(Identifier fkIdentifier) { return new ForeignKeyBuilderImpl( fkIdentifier ); } - protected static interface ForeignKeyBuilder { - public ForeignKeyBuilder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced); + protected interface ForeignKeyBuilder { + ForeignKeyBuilder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced); - public ForeignKeyInformation build(); + ForeignKeyInformation build(); } protected static class ForeignKeyBuilderImpl implements ForeignKeyBuilder { @@ -524,11 +546,9 @@ private QualifiedTableName extractKeyTableName(ResultSet resultSet, String prefi final String incomingTableName = resultSet.getString( prefix + "TABLE_NAME" ); return new QualifiedTableName( - new Schema.Name( - Identifier.toIdentifier( incomingCatalogName ), - Identifier.toIdentifier( incomingSchemaName ) - ), - Identifier.toIdentifier( incomingTableName ) + identifierHelper().fromMetaDataCatalogName( incomingCatalogName ), + identifierHelper().fromMetaDataSchemaName( incomingSchemaName ), + identifierHelper().fromMetaDataObjectName( incomingTableName ) ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/TestFkUpdating.java b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/TestFkUpdating.java new file mode 100644 index 000000000000..aa70651de8f4 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/schemaupdate/TestFkUpdating.java @@ -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 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 getRoles() { + return roles; + } + + public void setRoles(Set 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; + } + } +}