diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/MySQLDialect.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/MySQLDialect.java index 82b4a4b87..acee55f31 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/MySQLDialect.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/MySQLDialect.java @@ -22,6 +22,8 @@ import com.fr.third.org.hibernate.dialect.identity.MySQLIdentityColumnSupport; import com.fr.third.org.hibernate.dialect.pagination.AbstractLimitHandler; import com.fr.third.org.hibernate.dialect.pagination.LimitHandler; import com.fr.third.org.hibernate.dialect.pagination.LimitHelper; +import com.fr.third.org.hibernate.dialect.unique.MySQLUniqueDelegate; +import com.fr.third.org.hibernate.dialect.unique.UniqueDelegate; import com.fr.third.org.hibernate.engine.spi.RowSelection; import com.fr.third.org.hibernate.exception.LockAcquisitionException; import com.fr.third.org.hibernate.exception.LockTimeoutException; @@ -43,6 +45,8 @@ import com.fr.third.org.hibernate.type.StandardBasicTypes; @SuppressWarnings("deprecation") public class MySQLDialect extends Dialect { + private final UniqueDelegate uniqueDelegate; + private static final LimitHandler LIMIT_HANDLER = new AbstractLimitHandler() { @Override public String processSql(String sql, RowSelection selection) { @@ -196,6 +200,8 @@ public class MySQLDialect extends Dialect { getDefaultProperties().setProperty( Environment.MAX_FETCH_DEPTH, "2" ); getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); + + uniqueDelegate = new MySQLUniqueDelegate( this ); } protected void registerVarcharTypes() { @@ -234,6 +240,11 @@ public class MySQLDialect extends Dialect { ); } + @Override + public String getDropPrimaryKeyConstraintString(String constraintName) { + return " drop primary key "; + } + @Override public boolean supportsLimit() { return true; @@ -244,11 +255,6 @@ public class MySQLDialect extends Dialect { return " drop foreign key "; } - @Override - public String getDropPrimaryKeyConstraintString(String constraintName) { - return " drop primary key "; - } - @Override public LimitHandler getLimitHandler() { return LIMIT_HANDLER; @@ -427,6 +433,11 @@ public class MySQLDialect extends Dialect { return ps.getResultSet(); } + @Override + public UniqueDelegate getUniqueDelegate() { + return uniqueDelegate; + } + @Override public boolean supportsRowValueConstructorSyntax() { return true; diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/unique/DefaultUniqueDelegate.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/unique/DefaultUniqueDelegate.java index 836e3b68e..36ffdb5ec 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/unique/DefaultUniqueDelegate.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/unique/DefaultUniqueDelegate.java @@ -85,7 +85,7 @@ public class DefaultUniqueDelegate implements UniqueDelegate { final StringBuilder buf = new StringBuilder( "alter table " ); buf.append( tableName ); - buf.append(" drop constraint " ); + buf.append(getDropUnique()); if ( dialect.supportsIfExistsBeforeConstraintName() ) { buf.append( "if exists " ); } @@ -96,4 +96,7 @@ public class DefaultUniqueDelegate implements UniqueDelegate { return buf.toString(); } + protected String getDropUnique(){ + return " drop constraint "; + } } diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/unique/MySQLUniqueDelegate.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/unique/MySQLUniqueDelegate.java new file mode 100644 index 000000000..caab6c8e5 --- /dev/null +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/unique/MySQLUniqueDelegate.java @@ -0,0 +1,23 @@ +package com.fr.third.org.hibernate.dialect.unique; + +import com.fr.third.org.hibernate.dialect.Dialect; + +/** + * @author Andrea Boriero + */ +public class MySQLUniqueDelegate extends DefaultUniqueDelegate { + + /** + * Constructs MySQLUniqueDelegate + * + * @param dialect The dialect for which we are handling unique constraints + */ + public MySQLUniqueDelegate(Dialect dialect) { + super( dialect ); + } + + @Override + protected String getDropUnique() { + return " drop index "; + } +} \ No newline at end of file diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/internal/IndexInformationImpl.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/internal/IndexInformationImpl.java index 81bc14363..fb33abaa4 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/internal/IndexInformationImpl.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/internal/IndexInformationImpl.java @@ -21,12 +21,19 @@ import com.fr.third.org.hibernate.tool.schema.spi.SchemaManagementException; public class IndexInformationImpl implements IndexInformation { private final Identifier indexIdentifier; private final List columnList; + private boolean unique; public IndexInformationImpl(Identifier indexIdentifier, List columnList) { this.indexIdentifier = indexIdentifier; this.columnList = columnList; } + public IndexInformationImpl(Identifier indexIdentifier, List columnList, boolean unique) { + this.indexIdentifier = indexIdentifier; + this.columnList = columnList; + this.unique = unique; + } + @Override public Identifier getIndexIdentifier() { return indexIdentifier; @@ -37,6 +44,11 @@ public class IndexInformationImpl implements IndexInformation { return columnList; } + @Override + public boolean isUnique() { + return unique; + } + public static Builder builder(Identifier indexIdentifier) { return new Builder( indexIdentifier ); } @@ -44,6 +56,7 @@ public class IndexInformationImpl implements IndexInformation { public static class Builder { private final Identifier indexIdentifier; private final List columnList = new ArrayList(); + private boolean unique; public Builder(Identifier indexIdentifier) { this.indexIdentifier = indexIdentifier; @@ -54,13 +67,18 @@ public class IndexInformationImpl implements IndexInformation { return this; } + public Builder setUnique(boolean unique) { + this.unique = unique; + return this; + } + public IndexInformationImpl build() { if ( columnList.isEmpty() ) { throw new SchemaManagementException( "Attempt to resolve JDBC metadata failed to find columns for index [" + indexIdentifier.getText() + "]" ); } - return new IndexInformationImpl( indexIdentifier, Collections.unmodifiableList( columnList ) ); + return new IndexInformationImpl( indexIdentifier, Collections.unmodifiableList( columnList ), unique); } } } diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java index e98aef411..b1dbb4e9d 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/internal/InformationExtractorJdbcDatabaseMetaDataImpl.java @@ -710,6 +710,24 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information } try { + //处理唯一键 + ResultSet uniqueKeyResult = extractionContext.getJdbcDatabaseMetaData().getIndexInfo(catalogFilter, schemaFilter, tableName.getTableName().getText(), true, true); + try { + while (uniqueKeyResult.next()) { + if ( uniqueKeyResult.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic ) { + continue; + } + final Identifier indexIdentifier = DatabaseIdentifier.toIdentifier(uniqueKeyResult.getString("INDEX_NAME")); + IndexInformationImpl.Builder builder = builders.get( indexIdentifier ); + if ( builder == null ) { + builder = IndexInformationImpl.builder( indexIdentifier ).setUnique(true); + builders.put( indexIdentifier, builder ); + } + } + } finally { + uniqueKeyResult.close(); + } + ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getIndexInfo( catalogFilter, schemaFilter, diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/spi/IndexInformation.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/spi/IndexInformation.java index b5caeb1cf..b9426cc96 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/spi/IndexInformation.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/extract/spi/IndexInformation.java @@ -30,4 +30,6 @@ public interface IndexInformation { * @return The columns */ public List getIndexedColumns(); + + boolean isUnique(); } diff --git a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java index 0e08a9e46..d3e452571 100644 --- a/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java +++ b/fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java @@ -359,6 +359,29 @@ public abstract class AbstractSchemaMigrator implements SchemaMigrator { if ( uniqueConstraintStrategy != UniqueConstraintSchemaUpdateStrategy.SKIP ) { final Exporter exporter = dialect.getUniqueKeyExporter(); + Set identifiers = getUniqueKeyIdentifiers(table); + if (tableInfo != null) { + for (IndexInformation indexInfo : tableInfo.getIndexes()) { + if (!indexInfo.isUnique() || indexInfo.getIndexIdentifier().equals(tableInfo.getPrimaryKey().getPrimaryKeyIdentifier())) { + continue; + } + //如果旧的唯一键已经不存在, 则删除 + if (!identifiers.contains(indexInfo.getIndexIdentifier())) { + log.warn("delete unique key not existed in entity: " + indexInfo.getIndexIdentifier().getText()); + UniqueKey old = new UniqueKey(); + old.setTable(table); + old.setName(indexInfo.getIndexIdentifier().getText()); + applySqlStrings( + true, + exporter.getSqlDropStrings(old, metadata), + formatter, + options, + targets + ); + } + } + } + final Iterator ukItr = table.getUniqueKeyIterator(); while ( ukItr.hasNext() ) { final UniqueKey uniqueKey = (UniqueKey) ukItr.next(); @@ -392,6 +415,18 @@ public abstract class AbstractSchemaMigrator implements SchemaMigrator { } } + private Set getUniqueKeyIdentifiers(Table table) { + Set identifiers = new HashSet<>(); + Iterator uniqueKeys = table.getUniqueKeyIterator(); + while (uniqueKeys.hasNext()) { + UniqueKey uniqueKey = uniqueKeys.next(); + if (StringHelper.isNotEmpty(uniqueKey.getName())) { + identifiers.add(Identifier.toIdentifier(uniqueKey.getName())); + } + } + return identifiers; + } + private UniqueConstraintSchemaUpdateStrategy determineUniqueConstraintSchemaUpdateStrategy(Metadata metadata) { final ConfigurationService cfgService = ((MetadataImplementor) metadata).getMetadataBuildingOptions() .getServiceRegistry()