Changeset 7455
- Timestamp:
- Mar 6, 2018, 10:12:30 AM (5 years ago)
- Location:
- branches/3.12-stable/src/core/net/sf/basedb/core
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.12-stable/src/core/net/sf/basedb/core/ServiceSessionControl.java
r7396 r7455 346 346 347 347 // Check if the schema exists or not 348 boolean schemaExists = HibernateUtil.doReturningWork(session, new SchemaExistsWork( catalog, schema));348 boolean schemaExists = HibernateUtil.doReturningWork(session, new SchemaExistsWork(actualCatalog, actualSchema)); 349 349 installMode = schemaExists ? SchemaGenerator.Mode.UPDATE : SchemaGenerator.Mode.INSTALL; 350 350 if (log.isDebugEnabled()) log.debug("Mode: " +installMode); -
branches/3.12-stable/src/core/net/sf/basedb/core/hibernate/SchemaGenerator.java
r7397 r7455 22 22 package net.sf.basedb.core.hibernate; 23 23 24 import java.lang.reflect.Field;25 24 import java.sql.Connection; 25 import java.sql.DatabaseMetaData; 26 26 import java.sql.SQLException; 27 27 import java.sql.Statement; … … 30 30 import java.util.EnumSet; 31 31 import java.util.HashMap; 32 import java.util.Iterator; 32 33 import java.util.List; 33 34 import java.util.Map; 34 35 36 import net.sf.basedb.core.DatabaseException; 35 37 import net.sf.basedb.core.ProgressReporter; 36 38 import net.sf.basedb.core.StringUtil; 37 39 import net.sf.basedb.core.dbengine.DbEngine; 40 import net.sf.basedb.core.dbengine.TableInfo; 38 41 import net.sf.basedb.util.EqualsHelper; 39 42 40 43 import org.hibernate.boot.Metadata; 41 44 import org.hibernate.boot.model.naming.Identifier; 42 import org.hibernate.boot.model.relational.QualifiedName;43 import org.hibernate.boot.model.relational.QualifiedSequenceName;44 45 import org.hibernate.boot.model.relational.QualifiedTableName; 45 46 import org.hibernate.boot.spi.MetadataImplementor; 46 47 import org.hibernate.dialect.Dialect; 47 import org.hibernate.engine.jdbc.env.internal. JdbcEnvironmentImpl;48 import org.hibernate.engine.jdbc.env.internal.QualifiedObjectNameFormatterStandardImpl; 48 49 import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; 49 50 import org.hibernate.engine.jdbc.env.spi.QualifiedObjectNameFormatter; 50 51 import org.hibernate.jdbc.Work; 52 import org.hibernate.mapping.Table; 51 53 import org.hibernate.service.ServiceRegistry; 52 54 import org.hibernate.service.spi.ServiceRegistryImplementor; 53 55 import org.hibernate.tool.schema.SourceType; 54 56 import org.hibernate.tool.schema.TargetType; 57 import org.hibernate.tool.schema.extract.spi.DatabaseInformation; 58 import org.hibernate.tool.schema.extract.spi.TableInformation; 55 59 import org.hibernate.tool.schema.internal.SchemaCreatorImpl; 60 import org.hibernate.tool.schema.internal.exec.JdbcContext; 56 61 import org.hibernate.tool.schema.internal.ExceptionHandlerHaltImpl; 62 import org.hibernate.tool.schema.internal.Helper; 57 63 import org.hibernate.tool.schema.internal.HibernateSchemaManagementTool; 58 import org.hibernate.tool.schema.internal.IndividuallySchemaMigratorImpl;59 64 import org.hibernate.tool.schema.spi.ExceptionHandler; 60 65 import org.hibernate.tool.schema.spi.ExecutionOptions; 61 66 import org.hibernate.tool.schema.spi.SchemaCreator; 62 import org.hibernate.tool.schema.spi.SchemaMigrator;63 67 import org.hibernate.tool.schema.spi.ScriptSourceInput; 64 68 import org.hibernate.tool.schema.spi.ScriptTargetOutput; … … 117 121 ----------------------- 118 122 */ 123 @SuppressWarnings("unchecked") 119 124 @Override 120 125 public void execute(Connection connection) … … 131 136 String currentSql = null; 132 137 boolean autoCommit = connection.getAutoCommit(); 133 ForceQuotedTableNameFormatter tableNameFormatter = new ForceQuotedTableNameFormatter(metadata); 138 134 139 try 135 140 { … … 144 149 { 145 150 log.info("Generating schema update script"); 146 tableNameFormatter.applyWorkaroundForHibernateBug(); 147 SchemaMigrator schemaMigrator = new IndividuallySchemaMigratorImpl(tool, null); 148 schemaMigrator.doMigration(metadata, schemaUpdates, schemaUpdates); 151 152 DatabaseMetaData jdbcMetaData = connection.getMetaData(); 153 JdbcContext jdbcContext = tool.resolveJdbcContext(schemaUpdates.getConfigurationValues()); 154 JdbcEnvironment jdbcEnvironment = metadata.getDatabase().getJdbcEnvironment(); 155 156 QualifiedObjectNameFormatter tableNameFormatter = new QualifiedObjectNameFormatterStandardImpl(jdbcEnvironment.getNameQualifierSupport()); 157 158 DatabaseInformation hibernateDbInfo = Helper.buildDatabaseInformation(serviceRegistry, 159 tool.getDdlTransactionIsolator(jdbcContext), 160 metadata.getDatabase().getDefaultNamespace().getName()); 161 162 Iterator<Table> tables = metadata.collectTableMappings().iterator(); 163 while (tables.hasNext()) 164 { 165 Table table = tables.next(); 166 TableInfo jdbcTableInfo = new TableInfo(table, jdbcMetaData); 167 168 log.debug("Table: " + table + (jdbcTableInfo.existsInDb() ? " EXISTS" : "NOT FOUND")); 169 170 if (jdbcTableInfo.existsInDb()) 171 { 172 // This table exists in the database, we need to force Hibernate to check and ALTER it if needed 173 QualifiedTableName qft = table.getQualifiedTableName(); 174 175 // First try: let Hibernate use the default settings to find the table 176 TableInformation hibernateTableInfo = hibernateDbInfo.getTableInformation(qft); 177 178 if (log.isDebugEnabled()) log.debug(qft + ": " + hibernateTableInfo); 179 180 if (hibernateTableInfo == null) 181 { 182 // If that fails, we need to try again with unquoted table name 183 qft = new QualifiedTableName(qft.getCatalogName(), qft.getSchemaName(), Identifier.toIdentifier(table.getName(), false)); 184 hibernateTableInfo = hibernateDbInfo.getTableInformation(qft); 185 if (log.isDebugEnabled()) log.debug(qft + ": " + hibernateTableInfo); 186 187 // If this is null here we are in trouble!!! 188 if (hibernateTableInfo == null) 189 { 190 throw new DatabaseException("Table '" + table.getName() + "' exists, but Hibernate can't find any information about it. "+ 191 "Please report as a bug to the BASE developers"); 192 } 193 } 194 195 // To get the quoting, upper- and lower-case correct we need to re-create a new instance 196 // and do a search-and-replace in the SQL generated by Hibernate 197 qft = new QualifiedTableName(hibernateTableInfo.getName().getCatalogName(), hibernateTableInfo.getName().getSchemaName(), table.getNameIdentifier()); 198 String correctTableName = tableNameFormatter.format(qft, dialect); 199 String tableNameGeneratedByHibernate = tableNameFormatter.format(hibernateTableInfo.getName(), dialect); 200 if (log.isDebugEnabled()) 201 { 202 log.debug("Search-and-replace: " + tableNameGeneratedByHibernate + "-->" + correctTableName); 203 } 204 Iterator<String> it = (Iterator<String>)table.sqlAlterStrings(dialect, metadata, hibernateTableInfo, null, null); 205 while (it.hasNext()) 206 { 207 String sql = it.next(); 208 String modifiedSql = sql.replace(tableNameGeneratedByHibernate, correctTableName); 209 if (!sql.equals(modifiedSql)) 210 { 211 log.debug("Hibernate SQL: " + sql); 212 log.debug("Modified SQL: " + modifiedSql); 213 } 214 schemaUpdates.accept(modifiedSql); 215 } 216 } 217 else 218 { 219 String[] sql = dialect.getTableExporter().getSqlCreateStrings(table, metadata); 220 for (String s : sql) 221 { 222 schemaUpdates.accept(s); 223 } 224 } 225 } 149 226 } 150 227 else if (mode == Mode.INSTALL) … … 223 300 { 224 301 if (autoCommit != connection.getAutoCommit()) connection.setAutoCommit(autoCommit); 225 tableNameFormatter.resetWorkaroundForHibernateBug();226 302 if (stmt != null) 227 303 { … … 416 492 } 417 493 418 419 /**420 Replace the 'QualifiedObjectNameFormatter' with an implementation that forces421 all table names to be flagged as quoted. This is a hack to work around a bug422 in Hibernate which generates "alter table table-name add column ..."423 statements without quotes around the table-name which causes an error424 425 TODO - When (if?) this issue is fixed in Hibernate we can remove this workaround426 */427 static class ForceQuotedTableNameFormatter428 implements QualifiedObjectNameFormatter429 {430 431 private final Metadata metadata;432 private final JdbcEnvironment jdbc;433 private QualifiedObjectNameFormatter originalFormatter;434 435 ForceQuotedTableNameFormatter(Metadata metadata)436 {437 this.metadata = metadata;438 this.jdbc = metadata.getDatabase().getJdbcEnvironment();439 }440 441 @Override442 public String format(QualifiedTableName tableName, Dialect dialect)443 {444 QualifiedTableName quotedTableName = new QualifiedTableName(445 tableName.getCatalogName(),446 tableName.getSchemaName(),447 Identifier.toIdentifier(tableName.getTableName().getText(), true)448 );449 return originalFormatter.format(quotedTableName, dialect);450 }451 452 @Override453 public String format(QualifiedSequenceName sequenceName, Dialect dialect)454 {455 return originalFormatter.format(sequenceName, dialect);456 }457 458 @Override459 public String format(QualifiedName name, Dialect dialect)460 {461 return originalFormatter.format(name, dialect);462 }463 464 void applyWorkaroundForHibernateBug()465 {466 this.originalFormatter = jdbc.getQualifiedObjectNameFormatter();467 setFormatter(this);468 }469 470 void resetWorkaroundForHibernateBug()471 {472 if (originalFormatter != null) setFormatter(originalFormatter);473 }474 475 private void setFormatter(QualifiedObjectNameFormatter formatter)476 {477 try478 {479 Field f = JdbcEnvironmentImpl.class.getDeclaredField("qualifiedObjectNameFormatter");480 f.setAccessible(true);481 f.set(jdbc, formatter);482 }483 catch (Exception ex)484 {485 throw new RuntimeException(ex);486 }487 }488 489 }490 494 491 495 }
Note: See TracChangeset
for help on using the changeset viewer.