From 40aaaa9ca769258cd4bfc67761d9cf0fca1ab56e Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Fri, 5 Apr 2013 12:52:31 -0400 Subject: [PATCH] HHH-8149 Revert HHH-7797 in 4.1.x --- .../java/org/hibernate/cfg/Configuration.java | 36 +++-- .../org/hibernate/dialect/Cache71Dialect.java | 5 + .../org/hibernate/dialect/DB2Dialect.java | 16 +- .../java/org/hibernate/dialect/Dialect.java | 86 ++++------ .../java/org/hibernate/dialect/H2Dialect.java | 4 + .../org/hibernate/dialect/HSQLDialect.java | 4 + .../org/hibernate/dialect/IngresDialect.java | 7 + .../hibernate/dialect/RDMSOS2200Dialect.java | 7 + .../hibernate/dialect/SybaseASE15Dialect.java | 4 + .../hibernate/dialect/TimesTenDialect.java | 8 + .../dialect/unique/DB2UniqueDelegate.java | 109 ------------- .../dialect/unique/DefaultUniqueDelegate.java | 148 ------------------ .../dialect/unique/UniqueDelegate.java | 146 ----------------- .../java/org/hibernate/mapping/Index.java | 1 + .../java/org/hibernate/mapping/Table.java | 51 ++++-- .../java/org/hibernate/mapping/UniqueKey.java | 74 +++++++-- .../metamodel/relational/Database.java | 6 +- .../hibernate/metamodel/relational/Index.java | 13 +- .../hibernate/metamodel/relational/Table.java | 25 ++- .../metamodel/relational/UniqueKey.java | 64 ++++++-- .../UniqueConstraintTest.java | 14 +- .../test/constraint/ConstraintTest.java | 85 ---------- .../org/hibernate/testing/DialectChecks.java | 6 + 23 files changed, 285 insertions(+), 634 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/dialect/unique/DB2UniqueDelegate.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/dialect/unique/DefaultUniqueDelegate.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/dialect/unique/UniqueDelegate.java delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/constraint/ConstraintTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java index e445afdef1..f49a993249 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -50,7 +50,6 @@ import java.util.StringTokenizer; import java.util.TreeMap; import java.util.jar.JarFile; import java.util.zip.ZipEntry; - import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.MapsId; @@ -59,6 +58,10 @@ import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; +import org.jboss.logging.Logger; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; + import org.hibernate.AnnotationException; import org.hibernate.DuplicateMappingException; import org.hibernate.EmptyInterceptor; @@ -142,9 +145,6 @@ import org.hibernate.type.Type; import org.hibernate.type.TypeResolver; import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.UserType; -import org.jboss.logging.Logger; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; /** * An instance of Configuration allows the application @@ -1045,15 +1045,17 @@ public class Configuration implements Serializable { Table table = (Table) iter.next(); if ( table.isPhysicalTable() ) { - Iterator subIter = table.getUniqueKeyIterator(); - while ( subIter.hasNext() ) { - UniqueKey uk = (UniqueKey) subIter.next(); - String constraintString = uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema ); - if (constraintString != null) script.add( constraintString ); + if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) { + Iterator subIter = table.getUniqueKeyIterator(); + while ( subIter.hasNext() ) { + UniqueKey uk = (UniqueKey) subIter.next(); + String constraintString = uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema ); + if (constraintString != null) script.add( constraintString ); + } } - subIter = table.getIndexIterator(); + Iterator subIter = table.getIndexIterator(); while ( subIter.hasNext() ) { Index index = (Index) subIter.next(); script.add( @@ -1224,6 +1226,15 @@ public class Configuration implements Serializable { ) ); } + +//broken, 'cos we don't generate these with names in SchemaExport +// subIter = table.getUniqueKeyIterator(); +// while ( subIter.hasNext() ) { +// UniqueKey uk = (UniqueKey) subIter.next(); +// if ( tableInfo==null || tableInfo.getIndexMetadata( uk.getFilterName() ) == null ) { +// script.add( uk.sqlCreateString(dialect, mapping) ); +// } +// } } } @@ -1531,6 +1542,7 @@ public class Configuration implements Serializable { private void buildUniqueKeyFromColumnNames(Table table, String keyName, String[] columnNames) { keyName = normalizer.normalizeIdentifierQuoting( keyName ); + UniqueKey uc; int size = columnNames.length; Column[] columns = new Column[size]; Set unbound = new HashSet(); @@ -1547,10 +1559,10 @@ public class Configuration implements Serializable { unboundNoLogical.add( new Column( column ) ); } } - UniqueKey uk = table.getOrCreateUniqueKey( keyName ); for ( Column column : columns ) { if ( table.containsColumn( column ) ) { - uk.addColumn( column ); + uc = table.getOrCreateUniqueKey( keyName ); + uc.addColumn( table.getColumn( column ) ); unbound.remove( column ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Cache71Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Cache71Dialect.java index c2811e3b42..702b721531 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Cache71Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Cache71Dialect.java @@ -401,6 +401,11 @@ public class Cache71Dialect extends Dialect { return false; } + public boolean supportsUnique() { + // Does this dialect support the UNIQUE column syntax? + return true; + } + /** * The syntax used to add a foreign key constraint to a table. * diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java index 2e3397c464..4d7df4ca5b 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java @@ -30,13 +30,12 @@ import java.sql.Types; import org.hibernate.JDBCException; import org.hibernate.cfg.Environment; +import org.hibernate.dialect.function.AnsiTrimEmulationFunction; import org.hibernate.dialect.function.AvgWithArgumentCastFunction; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.dialect.unique.DB2UniqueDelegate; -import org.hibernate.dialect.unique.UniqueDelegate; import org.hibernate.exception.LockTimeoutException; import org.hibernate.exception.spi.SQLExceptionConversionDelegate; import org.hibernate.internal.util.JdbcExceptionHelper; @@ -50,8 +49,6 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; * @author Gavin King */ public class DB2Dialect extends Dialect { - - private final UniqueDelegate uniqueDelegate; public DB2Dialect() { super(); @@ -178,8 +175,6 @@ public class DB2Dialect extends Dialect { registerKeyword( "only" ); getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH ); - - uniqueDelegate = new DB2UniqueDelegate( this ); } @Override public String getLowercaseFunction() { @@ -284,6 +279,10 @@ public class DB2Dialect extends Dialect { return false; } @Override + public boolean supportsNotNullUnique() { + return false; + } + @Override public boolean supportsExistsInSelect() { return false; } @@ -458,11 +457,6 @@ public class DB2Dialect extends Dialect { }; } - @Override - public UniqueDelegate getUniqueDelegate() { - return uniqueDelegate; - } - @Override public String getNotExpression( String expression ) { return "not (" + expression + ")"; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 4f8e304b03..04a2ebf318 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -58,8 +58,6 @@ import org.hibernate.dialect.lock.PessimisticWriteSelectLockingStrategy; import org.hibernate.dialect.lock.SelectLockingStrategy; import org.hibernate.dialect.pagination.LegacyLimitHandler; import org.hibernate.dialect.pagination.LimitHandler; -import org.hibernate.dialect.unique.DefaultUniqueDelegate; -import org.hibernate.dialect.unique.UniqueDelegate; import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionImplementor; @@ -117,8 +115,6 @@ public abstract class Dialect implements ConversionContext { private final Properties properties = new Properties(); private final Map sqlFunctions = new HashMap(); private final Set sqlKeywords = new HashSet(); - - private final UniqueDelegate uniqueDelegate; // constructors and factory methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -207,8 +203,6 @@ public abstract class Dialect implements ConversionContext { registerHibernateType( Types.BLOB, StandardBasicTypes.BLOB.getName() ); registerHibernateType( Types.CLOB, StandardBasicTypes.CLOB.getName() ); registerHibernateType( Types.REAL, StandardBasicTypes.FLOAT.getName() ); - - uniqueDelegate = new DefaultUniqueDelegate( this ); } /** @@ -1834,6 +1828,23 @@ public abstract class Dialect implements ConversionContext { return true; } + /** + * Does this dialect support the UNIQUE column syntax? + * + * @return boolean + */ + public boolean supportsUnique() { + return true; + } + + /** + * Does this dialect support adding Unique constraints via create and alter table ? + * @return boolean + */ + public boolean supportsUniqueConstraintInCreateAlterTable() { + return true; + } + /** * The syntax used to add a column to a table (optional). * @@ -1899,6 +1910,16 @@ public abstract class Dialect implements ConversionContext { return " add constraint " + constraintName + " primary key "; } + /** + * The syntax used to add a unique constraint to a table. + * + * @param constraintName The name of the unique constraint. + * @return The "add unique" fragment + */ + public String getAddUniqueConstraintString(String constraintName) { + return " add constraint " + constraintName + " unique "; + } + public boolean hasSelfReferentialForeignKeyBug() { return false; } @@ -1968,6 +1989,10 @@ public abstract class Dialect implements ConversionContext { return true; } + public boolean supportsNotNullUnique() { + return true; + } + /** * Completely optional cascading drop clause * @@ -2320,56 +2345,7 @@ public abstract class Dialect implements ConversionContext { return false; } - public UniqueDelegate getUniqueDelegate() { - return uniqueDelegate; - } - public String getNotExpression( String expression ) { return "not " + expression; } - - /** - * Does this dialect support the UNIQUE column syntax? - * - * @return boolean - * - * @deprecated {@link #getUniqueDelegate()} should be overridden instead. - */ - @Deprecated - public boolean supportsUnique() { - return true; - } - - /** - * Does this dialect support adding Unique constraints via create and alter table ? - * - * @return boolean - * - * @deprecated {@link #getUniqueDelegate()} should be overridden instead. - */ - @Deprecated - public boolean supportsUniqueConstraintInCreateAlterTable() { - return true; - } - - /** - * The syntax used to add a unique constraint to a table. - * - * @param constraintName The name of the unique constraint. - * @return The "add unique" fragment - * - * @deprecated {@link #getUniqueDelegate()} should be overridden instead. - */ - @Deprecated - public String getAddUniqueConstraintString(String constraintName) { - return " add constraint " + constraintName + " unique "; - } - - /** - * @deprecated {@link #getUniqueDelegate()} should be overridden instead. - */ - @Deprecated - public boolean supportsNotNullUnique() { - return true; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java index 9adc838f0b..e4bc9bdfc8 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java @@ -216,6 +216,10 @@ public class H2Dialect extends Dialect { return " for update"; } + public boolean supportsUnique() { + return true; + } + public boolean supportsLimit() { return true; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java index f74b900dd5..d0b176fa9f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java @@ -246,6 +246,10 @@ public class HSQLDialect extends Dialect { return ""; } + public boolean supportsUnique() { + return false; + } + public boolean supportsLimit() { return true; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/IngresDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/IngresDialect.java index e5b9f8a20e..a7dbaf194c 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/IngresDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/IngresDialect.java @@ -306,6 +306,13 @@ public class IngresDialect extends Dialect { return true; } + /** + * Ingres explicitly needs "unique not null", because "with null" is default + */ + public boolean supportsNotNullUnique() { + return false; + } + /** * Does this dialect support temporary tables? */ diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java index ccec37a7c7..6d45c1c6d5 100755 --- a/hibernate-core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java @@ -240,6 +240,13 @@ public class RDMSOS2200Dialect extends Dialect { return ""; // Original Dialect.java returns " for update"; } + /** + * RDMS does not support adding Unique constraints via create and alter table. + */ + public boolean supportsUniqueConstraintInCreateAlterTable() { + return true; + } + // Verify the state of this new method in Hibernate 3.0 Dialect.java /** * RDMS does not support Cascade Deletes. diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java index 01f8d25776..423ced7cb7 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java @@ -422,6 +422,10 @@ public class SybaseASE15Dialect extends SybaseDialect { return false; } + public boolean supportsUniqueConstraintInCreateAlterTable() { + return false; + } + public String getCrossJoinSeparator() { return ", "; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/TimesTenDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/TimesTenDialect.java index f76e3099a1..b2f611aeb2 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/TimesTenDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/TimesTenDialect.java @@ -102,6 +102,14 @@ public class TimesTenDialect extends Dialect { public boolean qualifyIndexName() { return false; } + + public boolean supportsUnique() { + return false; + } + + public boolean supportsUniqueConstraintInCreateAlterTable() { + return false; + } public String getAddColumnString() { return "add"; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/unique/DB2UniqueDelegate.java b/hibernate-core/src/main/java/org/hibernate/dialect/unique/DB2UniqueDelegate.java deleted file mode 100644 index 852b7c7854..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/dialect/unique/DB2UniqueDelegate.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @authors tag. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * 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, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * 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, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -package org.hibernate.dialect.unique; - -import java.util.Iterator; - -import org.hibernate.dialect.Dialect; -import org.hibernate.metamodel.relational.Column; -import org.hibernate.metamodel.relational.Index; -import org.hibernate.metamodel.relational.UniqueKey; - -/** - * DB2 does not allow unique constraints on nullable columns. Rather than - * forcing "not null", use unique *indexes* instead. - * - * @author Brett Meyer - */ -public class DB2UniqueDelegate extends DefaultUniqueDelegate { - - public DB2UniqueDelegate( Dialect dialect ) { - super( dialect ); - } - - @Override - public String applyUniquesOnAlter( org.hibernate.mapping.UniqueKey uniqueKey, - String defaultCatalog, String defaultSchema ) { - if ( hasNullable( uniqueKey ) ) { - return org.hibernate.mapping.Index.buildSqlCreateIndexString( - dialect, uniqueKey.getName(), uniqueKey.getTable(), - uniqueKey.columnIterator(), true, defaultCatalog, - defaultSchema ); - } else { - return super.applyUniquesOnAlter( - uniqueKey, defaultCatalog, defaultSchema ); - } - } - - @Override - public String applyUniquesOnAlter( UniqueKey uniqueKey ) { - if ( hasNullable( uniqueKey ) ) { - return Index.buildSqlCreateIndexString( - dialect, uniqueKey.getName(), uniqueKey.getTable(), - uniqueKey.getColumns(), true ); - } else { - return super.applyUniquesOnAlter( uniqueKey ); - } - } - - @Override - public String dropUniquesOnAlter( org.hibernate.mapping.UniqueKey uniqueKey, - String defaultCatalog, String defaultSchema ) { - if ( hasNullable( uniqueKey ) ) { - return org.hibernate.mapping.Index.buildSqlDropIndexString( - dialect, uniqueKey.getTable(), uniqueKey.getName(), - defaultCatalog, defaultSchema ); - } else { - return super.dropUniquesOnAlter( - uniqueKey, defaultCatalog, defaultSchema ); - } - } - - @Override - public String dropUniquesOnAlter( UniqueKey uniqueKey ) { - if ( hasNullable( uniqueKey ) ) { - return Index.buildSqlDropIndexString( - dialect, uniqueKey.getTable(), uniqueKey.getName() ); - } else { - return super.dropUniquesOnAlter( uniqueKey ); - } - } - - private boolean hasNullable( org.hibernate.mapping.UniqueKey uniqueKey ) { - Iterator iter = uniqueKey.getColumnIterator(); - while ( iter.hasNext() ) { - if ( ( ( org.hibernate.mapping.Column ) iter.next() ).isNullable() ) { - return true; - } - } - return false; - } - - private boolean hasNullable( UniqueKey uniqueKey ) { - Iterator iter = uniqueKey.getColumns().iterator(); - while ( iter.hasNext() ) { - if ( ( ( Column ) iter.next() ).isNullable() ) { - return true; - } - } - return false; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/unique/DefaultUniqueDelegate.java b/hibernate-core/src/main/java/org/hibernate/dialect/unique/DefaultUniqueDelegate.java deleted file mode 100644 index 09e1d7e75d..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/dialect/unique/DefaultUniqueDelegate.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @authors tag. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * 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, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * 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, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -package org.hibernate.dialect.unique; - -import java.util.Iterator; - -import org.hibernate.dialect.Dialect; -import org.hibernate.metamodel.relational.Column; -import org.hibernate.metamodel.relational.Table; -import org.hibernate.metamodel.relational.UniqueKey; - -/** - * The default UniqueDelegate implementation for most dialects. Uses - * separate create/alter statements to apply uniqueness to a column. - * - * @author Brett Meyer - */ -public class DefaultUniqueDelegate implements UniqueDelegate { - - protected final Dialect dialect; - - public DefaultUniqueDelegate( Dialect dialect ) { - this.dialect = dialect; - } - - @Override - public String applyUniqueToColumn( org.hibernate.mapping.Column column ) { - return ""; - } - - @Override - public String applyUniqueToColumn( Column column ) { - return ""; - } - - @Override - public String applyUniquesToTable( org.hibernate.mapping.Table table ) { - return ""; - } - - @Override - public String applyUniquesToTable( Table table ) { - return ""; - } - - @Override - public String applyUniquesOnAlter( org.hibernate.mapping.UniqueKey uniqueKey, - String defaultCatalog, String defaultSchema ) { - // Do this here, rather than allowing UniqueKey/Constraint to do it. - // We need full, simplified control over whether or not it happens. - return new StringBuilder( "alter table " ) - .append( uniqueKey.getTable().getQualifiedName( - dialect, defaultCatalog, defaultSchema ) ) - .append( " add constraint " ) - .append( uniqueKey.getName() ) - .append( uniqueConstraintSql( uniqueKey ) ) - .toString(); - } - - @Override - public String applyUniquesOnAlter( UniqueKey uniqueKey ) { - // Do this here, rather than allowing UniqueKey/Constraint to do it. - // We need full, simplified control over whether or not it happens. - return new StringBuilder( "alter table " ) - .append( uniqueKey.getTable().getQualifiedName( dialect ) ) - .append( " add constraint " ) - .append( uniqueKey.getName() ) - .append( uniqueConstraintSql( uniqueKey ) ) - .toString(); - } - - @Override - public String dropUniquesOnAlter( org.hibernate.mapping.UniqueKey uniqueKey, - String defaultCatalog, String defaultSchema ) { - // Do this here, rather than allowing UniqueKey/Constraint to do it. - // We need full, simplified control over whether or not it happens. - return new StringBuilder( "alter table " ) - .append( uniqueKey.getTable().getQualifiedName( - dialect, defaultCatalog, defaultSchema ) ) - .append( " drop constraint " ) - .append( dialect.quote( uniqueKey.getName() ) ) - .toString(); - } - - @Override - public String dropUniquesOnAlter( UniqueKey uniqueKey ) { - // Do this here, rather than allowing UniqueKey/Constraint to do it. - // We need full, simplified control over whether or not it happens. - return new StringBuilder( "alter table " ) - .append( uniqueKey.getTable().getQualifiedName( dialect ) ) - .append( " drop constraint " ) - .append( dialect.quote( uniqueKey.getName() ) ) - .toString(); - } - - @Override - public String uniqueConstraintSql( org.hibernate.mapping.UniqueKey uniqueKey ) { - StringBuilder sb = new StringBuilder(); - sb.append( " unique (" ); - Iterator columnIterator = uniqueKey.getColumnIterator(); - while ( columnIterator.hasNext() ) { - org.hibernate.mapping.Column column - = (org.hibernate.mapping.Column) columnIterator.next(); - sb.append( column.getQuotedName( dialect ) ); - if ( columnIterator.hasNext() ) { - sb.append( ", " ); - } - } - - return sb.append( ')' ).toString(); - } - - @Override - public String uniqueConstraintSql( UniqueKey uniqueKey ) { - StringBuilder sb = new StringBuilder(); - sb.append( " unique (" ); - Iterator columnIterator = uniqueKey.getColumns().iterator(); - while ( columnIterator.hasNext() ) { - org.hibernate.mapping.Column column - = (org.hibernate.mapping.Column) columnIterator.next(); - sb.append( column.getQuotedName( dialect ) ); - if ( columnIterator.hasNext() ) { - sb.append( ", " ); - } - } - - return sb.append( ')' ).toString(); - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/unique/UniqueDelegate.java b/hibernate-core/src/main/java/org/hibernate/dialect/unique/UniqueDelegate.java deleted file mode 100644 index 4cd3c346d6..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/dialect/unique/UniqueDelegate.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @authors tag. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * 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, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * 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, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -package org.hibernate.dialect.unique; - -import org.hibernate.metamodel.relational.Column; -import org.hibernate.metamodel.relational.Table; -import org.hibernate.metamodel.relational.UniqueKey; - -/** - * Dialect-level delegate in charge of applying "uniqueness" to a column. - * Uniqueness can be defined in 1 of 3 ways: - * - * 1.) Add a unique constraint via separate alter table statements. - * 2.) Add a unique constraint via dialect-specific syntax in table create statement. - * 3.) Add "unique" syntax to the column itself. - * - * #1 & #2 are preferred, if possible -- #3 should be solely a fall-back. - * - * TODO: This could eventually be simplified. With AST, 1 "applyUniqueness" - * method might be possible. But due to .cfg and .mapping still resolving - * around StringBuilders, separate methods were needed. - * - * See HHH-7797. - * - * @author Brett Meyer - */ -public interface UniqueDelegate { - - /** - * If the dialect does not supports unique constraints, this method should - * return the syntax necessary to mutate the column definition - * (usually "unique"). - * - * @param column - * @return String - */ - public String applyUniqueToColumn( org.hibernate.mapping.Column column ); - - /** - * If the dialect does not supports unique constraints, this method should - * return the syntax necessary to mutate the column definition - * (usually "unique"). - * - * @param column - * @return String - */ - public String applyUniqueToColumn( Column column ); - - /** - * If constraints are supported, but not in seperate alter statements, - * return uniqueConstraintSql in order to add the constraint to the - * original table definition. - * - * @param table - * @return String - */ - public String applyUniquesToTable( org.hibernate.mapping.Table table ); - - /** - * If constraints are supported, but not in seperate alter statements, - * return uniqueConstraintSql in order to add the constraint to the - * original table definition. - * - * @param table - * @return String - */ - public String applyUniquesToTable( Table table ); - - /** - * If creating unique constraints in separate alter statements is - * supported, generate the necessary "alter" syntax for the given key. - * - * @param uniqueKey - * @param defaultCatalog - * @param defaultSchema - * @return String - */ - public String applyUniquesOnAlter( org.hibernate.mapping.UniqueKey uniqueKey, - String defaultCatalog, String defaultSchema ); - - /** - * If creating unique constraints in separate alter statements is - * supported, generate the necessary "alter" syntax for the given key. - * - * @param uniqueKey - * @return String - */ - public String applyUniquesOnAlter( UniqueKey uniqueKey ); - - /** - * If dropping unique constraints in separate alter statements is - * supported, generate the necessary "alter" syntax for the given key. - * - * @param uniqueKey - * @param defaultCatalog - * @param defaultSchema - * @return String - */ - public String dropUniquesOnAlter( org.hibernate.mapping.UniqueKey uniqueKey, - String defaultCatalog, String defaultSchema ); - - /** - * If dropping unique constraints in separate alter statements is - * supported, generate the necessary "alter" syntax for the given key. - * - * @param uniqueKey - * @return String - */ - public String dropUniquesOnAlter( UniqueKey uniqueKey ); - - /** - * Generates the syntax necessary to create the unique constraint (reused - * by all methods). Ex: "unique (column1, column2, ...)" - * - * @param uniqueKey - * @return String - */ - public String uniqueConstraintSql( org.hibernate.mapping.UniqueKey uniqueKey ); - - /** - * Generates the syntax necessary to create the unique constraint (reused - * by all methods). Ex: "unique (column1, column2, ...)" - * - * @param uniqueKey - * @return String - */ - public String uniqueConstraintSql( UniqueKey uniqueKey ); -} diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Index.java b/hibernate-core/src/main/java/org/hibernate/mapping/Index.java index da70576a05..f91fc55694 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Index.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Index.java @@ -79,6 +79,7 @@ public class Index implements RelationalModel, Serializable { String defaultCatalog, String defaultSchema ) { + //TODO handle supportsNotNullUnique=false, but such a case does not exist in the wild so far StringBuilder buf = new StringBuilder( "create" ) .append( unique ? " unique" : 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 b6dc2982fb..b41ad52db6 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java @@ -26,6 +26,7 @@ package org.hibernate.mapping; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -422,13 +423,11 @@ public class Table implements RelationalModel, Serializable { alter.append( " not null" ); } - if ( column.isUnique() ) { - uniqueIndexInteger++; - UniqueKey uk = getOrCreateUniqueKey( - "UK_" + name + "_" + uniqueIndexInteger); - uk.addColumn( column ); - alter.append( dialect.getUniqueDelegate() - .applyUniqueToColumn( column ) ); + boolean useUniqueConstraint = column.isUnique() && + dialect.supportsUnique() && + ( column.isNullable() || dialect.supportsNotNullUnique() ); + if ( useUniqueConstraint ) { + alter.append( " unique" ); } if ( column.hasCheckConstraint() && dialect.supportsColumnCheck() ) { @@ -526,16 +525,20 @@ public class Table implements RelationalModel, Serializable { } } - - if ( col.isUnique() ) { - uniqueIndexInteger++; - UniqueKey uk = getOrCreateUniqueKey( - "uc_" + name + "_" + uniqueIndexInteger); - uk.addColumn( col ); - buf.append( dialect.getUniqueDelegate() - .applyUniqueToColumn( col ) ); + + boolean useUniqueConstraint = col.isUnique() && + ( col.isNullable() || dialect.supportsNotNullUnique() ); + if ( useUniqueConstraint ) { + if ( dialect.supportsUnique() ) { + buf.append( " unique" ); + } + else { + UniqueKey uk = getOrCreateUniqueKey( + "UK_" + name + '_' + uniqueIndexInteger ); + uk.addColumn( col ); + } } - + if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) { buf.append( " check (" ) .append( col.getCheckConstraint() ) @@ -557,7 +560,21 @@ public class Table implements RelationalModel, Serializable { .append( getPrimaryKey().sqlConstraintString( dialect ) ); } - buf.append( dialect.getUniqueDelegate().applyUniquesToTable( this ) ); + if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { + Iterator ukiter = getUniqueKeyIterator(); + while ( ukiter.hasNext() ) { + UniqueKey uk = (UniqueKey) ukiter.next(); + String constraint = uk.sqlConstraintString( dialect ); + if ( constraint != null ) { + buf.append( ", " ).append( constraint ); + } + } + } + /*Iterator idxiter = getIndexIterator(); + while ( idxiter.hasNext() ) { + Index idx = (Index) idxiter.next(); + buf.append(',').append( idx.sqlConstraintString(dialect) ); + }*/ if ( dialect.supportsTableCheck() ) { Iterator chiter = checkConstraints.iterator(); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/UniqueKey.java b/hibernate-core/src/main/java/org/hibernate/mapping/UniqueKey.java index e5613817b9..f703f88a4c 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/UniqueKey.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/UniqueKey.java @@ -22,39 +22,89 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.mapping; +import java.util.Iterator; + import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.Mapping; /** * A relational unique key constraint * - * @author Brett Meyer + * @author Gavin King */ public class UniqueKey extends Constraint { + public String sqlConstraintString(Dialect dialect) { + StringBuilder buf = new StringBuilder( "unique (" ); + boolean hadNullableColumn = false; + Iterator iter = getColumnIterator(); + while ( iter.hasNext() ) { + Column column = (Column) iter.next(); + if ( !hadNullableColumn && column.isNullable() ) { + hadNullableColumn = true; + } + buf.append( column.getQuotedName( dialect ) ); + if ( iter.hasNext() ) { + buf.append( ", " ); + } + } + //do not add unique constraint on DB not supporting unique and nullable columns + return !hadNullableColumn || dialect.supportsNotNullUnique() ? + buf.append( ')' ).toString() : + null; + } + @Override public String sqlConstraintString( Dialect dialect, String constraintName, String defaultCatalog, String defaultSchema) { -// return dialect.getUniqueDelegate().uniqueConstraintSql( this ); - // Not used. - return ""; + StringBuilder buf = new StringBuilder( + dialect.getAddUniqueConstraintString( constraintName ) + ).append( '(' ); + Iterator iter = getColumnIterator(); + boolean nullable = false; + while ( iter.hasNext() ) { + Column column = (Column) iter.next(); + if ( !nullable && column.isNullable() ) nullable = true; + buf.append( column.getQuotedName( dialect ) ); + if ( iter.hasNext() ) buf.append( ", " ); + } + return !nullable || dialect.supportsNotNullUnique() ? buf.append( ')' ).toString() : null; } @Override - public String sqlCreateString(Dialect dialect, Mapping p, - String defaultCatalog, String defaultSchema) { - return dialect.getUniqueDelegate().applyUniquesOnAlter( - this, defaultCatalog, defaultSchema ); + public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) { + if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { + return super.sqlCreateString( dialect, p, defaultCatalog, defaultSchema ); + } + else { + return Index.buildSqlCreateIndexString( dialect, getName(), getTable(), getColumnIterator(), true, + defaultCatalog, defaultSchema ); + } } @Override - public String sqlDropString(Dialect dialect, String defaultCatalog, - String defaultSchema) { - return dialect.getUniqueDelegate().dropUniquesOnAlter( - this, defaultCatalog, defaultSchema ); + public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) { + if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { + return super.sqlDropString( dialect, defaultCatalog, defaultSchema ); + } + else { + return Index.buildSqlDropIndexString( dialect, getTable(), getName(), defaultCatalog, defaultSchema ); + } + } + + @Override + public boolean isGenerated(Dialect dialect) { + if ( dialect.supportsNotNullUnique() ) return true; + Iterator iter = getColumnIterator(); + while ( iter.hasNext() ) { + if ( ( (Column) iter.next() ).isNullable() ) { + return false; + } + } + return true; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Database.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Database.java index 3291b967ed..f15f565790 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Database.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Database.java @@ -115,8 +115,10 @@ public class Database { for ( Schema schema : schemaMap.values() ) { for ( Table table : schema.getTables() ) { - for ( UniqueKey uniqueKey : table.getUniqueKeys() ) { - addSqlCreateStrings( dialect, exportIdentifiers, script, uniqueKey ); + if ( ! dialect.supportsUniqueConstraintInCreateAlterTable() ) { + for ( UniqueKey uniqueKey : table.getUniqueKeys() ) { + addSqlCreateStrings( dialect, exportIdentifiers, script, uniqueKey ); + } } for ( Index index : table.getIndexes() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Index.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Index.java index 2eb119c914..20b4356ebc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Index.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Index.java @@ -63,6 +63,7 @@ public class Index extends AbstractConstraint implements Constraint { Iterable columns, boolean unique ) { + //TODO handle supportsNotNullUnique=false, but such a case does not exist in the wild so far StringBuilder buf = new StringBuilder( "create" ) .append( unique ? " unique" : @@ -88,18 +89,6 @@ public class Index extends AbstractConstraint implements Constraint { return buf.toString(); } - public static String buildSqlDropIndexString( - Dialect dialect, - TableSpecification table, - String name - ) { - return "drop index " + - StringHelper.qualify( - table.getQualifiedName( dialect ), - name - ); - } - public String sqlConstraintStringInAlterTable(Dialect dialect) { StringBuilder buf = new StringBuilder( " index (" ); boolean first = true; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Table.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Table.java index b252c01951..094c6ecb94 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/Table.java @@ -199,12 +199,16 @@ public class Table extends AbstractTableSpecification implements Exportable { } - if ( col.isUnique() ) { - UniqueKey uk = getOrCreateUniqueKey( col.getColumnName() - .encloseInQuotesIfQuoted( dialect ) + '_' ); - uk.addColumn( col ); - buf.append( dialect.getUniqueDelegate() - .applyUniqueToColumn( col ) ); + boolean useUniqueConstraint = col.isUnique() && + ( col.isNullable() || dialect.supportsNotNullUnique() ); + if ( useUniqueConstraint ) { + if ( dialect.supportsUnique() ) { + buf.append( " unique" ); + } + else { + UniqueKey uk = getOrCreateUniqueKey( col.getColumnName().encloseInQuotesIfQuoted( dialect ) + '_' ); + uk.addColumn( col ); + } } if ( col.getCheckCondition() != null && dialect.supportsColumnCheck() ) { @@ -223,7 +227,14 @@ public class Table extends AbstractTableSpecification implements Exportable { .append( getPrimaryKey().sqlConstraintStringInCreateTable( dialect ) ); } - buf.append( dialect.getUniqueDelegate().applyUniquesToTable( this ) ); + if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { + for ( UniqueKey uk : uniqueKeys.values() ) { + String constraint = uk.sqlConstraintStringInCreateTable( dialect ); + if ( constraint != null ) { + buf.append( ", " ).append( constraint ); + } + } + } if ( dialect.supportsTableCheck() ) { for ( CheckConstraint checkConstraint : checkConstraints ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/UniqueKey.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/UniqueKey.java index f11cb2ee89..150c9a32c9 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/UniqueKey.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/UniqueKey.java @@ -48,20 +48,60 @@ public class UniqueKey extends AbstractConstraint implements Constraint { } @Override - public String[] sqlCreateStrings(Dialect dialect) { - String s = dialect.getUniqueDelegate().applyUniquesOnAlter(this); - return StringHelper.toArrayElement( s ); + public boolean isCreationVetoed(Dialect dialect) { + if ( dialect.supportsNotNullUnique() ) { + return false; + } + + for ( Column column : getColumns() ) { + if ( column.isNullable() ) { + return true; + } + } + return false; + } + + public String sqlConstraintStringInCreateTable(Dialect dialect) { + StringBuilder buf = new StringBuilder( "unique (" ); + boolean hadNullableColumn = false; + boolean first = true; + for ( Column column : getColumns() ) { + if ( first ) { + first = false; + } + else { + buf.append( ", " ); + } + if ( !hadNullableColumn && column.isNullable() ) { + hadNullableColumn = true; + } + buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) ); + } + //do not add unique constraint on DB not supporting unique and nullable columns + return !hadNullableColumn || dialect.supportsNotNullUnique() ? + buf.append( ')' ).toString() : + null; } @Override - public String[] sqlDropStrings(Dialect dialect) { - String s = dialect.getUniqueDelegate().dropUniquesOnAlter(this); - return StringHelper.toArrayElement( s ); - } - - @Override - protected String sqlConstraintStringInAlterTable(Dialect dialect) { - // not used - return ""; + public String sqlConstraintStringInAlterTable(Dialect dialect) { + StringBuilder buf = new StringBuilder( + dialect.getAddUniqueConstraintString( getName() ) + ).append( '(' ); + boolean nullable = false; + boolean first = true; + for ( Column column : getColumns() ) { + if ( first ) { + first = false; + } + else { + buf.append( ", " ); + } + if ( !nullable && column.isNullable() ) { + nullable = true; + } + buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) ); + } + return !nullable || dialect.supportsNotNullUnique() ? buf.append( ')' ).toString() : null; } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/uniqueconstraint/UniqueConstraintTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/uniqueconstraint/UniqueConstraintTest.java index 078fa476f5..0e42287003 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/uniqueconstraint/UniqueConstraintTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/uniqueconstraint/UniqueConstraintTest.java @@ -15,6 +15,8 @@ import org.hibernate.JDBCException; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.mapping.UniqueKey; +import org.hibernate.testing.DialectChecks; +import org.hibernate.testing.RequiresDialectFeature; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.junit.Test; @@ -35,6 +37,7 @@ public class UniqueConstraintTest extends BaseCoreFunctionalTestCase { } @Test + @RequiresDialectFeature( DialectChecks.SupportNotNullUnique.class ) public void testUniquenessConstraintWithSuperclassProperty() throws Exception { Session s = openSession(); Transaction tx = s.beginTransaction(); @@ -72,7 +75,7 @@ public class UniqueConstraintTest extends BaseCoreFunctionalTestCase { Iterator iterator = configuration().getTableMappings(); org.hibernate.mapping.Table tableA = null; org.hibernate.mapping.Table tableB = null; - while( iterator.hasNext() ) { + while ( iterator.hasNext() ) { org.hibernate.mapping.Table table = iterator.next(); if ( table.getName().equals( "UniqueNoNameA" ) ) { tableA = table; @@ -81,14 +84,13 @@ public class UniqueConstraintTest extends BaseCoreFunctionalTestCase { tableB = table; } } - + if ( tableA == null || tableB == null ) { fail( "Could not find the expected tables." ); } - - UniqueKey ukA = (UniqueKey) tableA.getUniqueKeyIterator().next(); - UniqueKey ukB = (UniqueKey) tableB.getUniqueKeyIterator().next(); - assertFalse( ukA.getName().equals( ukB.getName() ) ); + + assertFalse( ( (UniqueKey) tableA.getUniqueKeyIterator().next() ).getName().equals( + ( (UniqueKey) tableB.getUniqueKeyIterator().next() ).getName() ) ); } @Entity diff --git a/hibernate-core/src/test/java/org/hibernate/test/constraint/ConstraintTest.java b/hibernate-core/src/test/java/org/hibernate/test/constraint/ConstraintTest.java deleted file mode 100644 index 5685d986d8..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/constraint/ConstraintTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @authors tag. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * 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, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * 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, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -package org.hibernate.test.constraint; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; - -import org.hibernate.mapping.Column; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.junit.Test; - -/** - * HHH-7797 re-wrote the way dialects handle unique constraints. Test - * variations of unique & not null to ensure the constraints are created - * correctly for each dialect. - * - * @author Brett Meyer - */ -@TestForIssue( jiraKey = "HHH-7797" ) -public class ConstraintTest extends BaseCoreFunctionalTestCase { - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Entity1.class - }; - } - - @Test - public void testConstraints() { - Column column = (Column) configuration().getClassMapping( Entity1.class.getName() ) - .getProperty( "foo1" ).getColumnIterator().next(); - assertFalse( column.isNullable() ); - assertTrue( column.isUnique() ); - - column = (Column) configuration().getClassMapping( Entity1.class.getName() ) - .getProperty( "foo2" ).getColumnIterator().next(); - assertTrue( column.isNullable() ); - assertTrue( column.isUnique() ); - - column = (Column) configuration().getClassMapping( Entity1.class.getName() ) - .getProperty( "id" ).getColumnIterator().next(); - assertFalse( column.isNullable() ); - assertTrue( column.isUnique() ); - } - - @Entity - @Table( name = "Entity1" ) - public static class Entity1 { - @Id - @GeneratedValue - @javax.persistence.Column( nullable = false, unique = true) - public long id; - - @javax.persistence.Column( nullable = false, unique = true) - public String foo1; - - @javax.persistence.Column( nullable = true, unique = true) - public String foo2; - } -} \ No newline at end of file diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/DialectChecks.java b/hibernate-testing/src/main/java/org/hibernate/testing/DialectChecks.java index 8408818ca0..a2e56fdda2 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/DialectChecks.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/DialectChecks.java @@ -92,6 +92,12 @@ abstract public class DialectChecks { } } + public static class SupportNotNullUnique implements DialectCheck { + public boolean isMatch(Dialect dialect) { + return dialect.supportsNotNullUnique(); + } + } + public static class SupportLimitCheck implements DialectCheck { public boolean isMatch(Dialect dialect) { return dialect.supportsLimit();