HHH-7797 Block "unique" syntax on a column if a constraint can/will be

used
This commit is contained in:
Brett Meyer 2012-12-07 16:19:54 -05:00 committed by Brett Meyer
parent c64b8bc4ae
commit 2ae841db66
5 changed files with 67 additions and 57 deletions

View File

@ -1977,6 +1977,11 @@ public abstract class Dialect implements ConversionContext {
return true;
}
/**
* Does this dialect support columns that are both unique and not null.
*
* @return True if supported, false otherwise.
*/
public boolean supportsNotNullUnique() {
return true;
}

View File

@ -423,10 +423,13 @@ public class Table implements RelationalModel, Serializable {
alter.append( " not null" );
}
boolean useUniqueConstraint = column.isUnique() &&
dialect.supportsUnique() &&
( column.isNullable() || dialect.supportsNotNullUnique() );
if ( useUniqueConstraint ) {
// If the column is 1.) unique, 2.) the dialect supports the
// unique syntax, 3.) the column is nullable or supports
// "not null unique", and 4.) a constraint will not be created
if ( column.isUnique() && dialect.supportsUnique()
&& ( column.isNullable()
|| dialect.supportsNotNullUnique() )
&& !dialect.supportsUniqueConstraintInCreateAlterTable() ) {
alter.append( " unique" );
}
@ -524,17 +527,21 @@ public class Table implements RelationalModel, Serializable {
}
}
boolean useUniqueConstraint = col.isUnique() &&
( col.isNullable() || dialect.supportsNotNullUnique() );
if ( useUniqueConstraint ) {
if ( dialect.supportsUnique() ) {
buf.append( " unique" );
}
else {
// If the column is 1.) unique and nullable or 2.) unique,
// not null, and the dialect supports unique not null
if ( col.isUnique()
&& ( col.isNullable()
|| dialect.supportsNotNullUnique() ) ) {
if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
// If the constraint is supported, do not add to the column syntax.
UniqueKey uk = getOrCreateUniqueKey( col.getQuotedName( dialect ) + '_' );
uk.addColumn( col );
}
else if ( dialect.supportsUnique() ) {
// Otherwise, add to the column syntax if supported.
buf.append( " unique" );
}
}
if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {

View File

@ -35,23 +35,21 @@ import org.hibernate.engine.spi.Mapping;
public class UniqueKey extends Constraint {
public String sqlConstraintString(Dialect dialect) {
// TODO: This may not be necessary, but not all callers currently
// check it on their own. Go through their logic.
if ( !isGenerated( dialect ) ) return null;
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;
return buf.append( ')' ).toString();
}
@Override
@ -60,18 +58,19 @@ public class UniqueKey extends Constraint {
String constraintName,
String defaultCatalog,
String defaultSchema) {
// TODO: This may not be necessary, but not all callers currently
// check it on their own. Go through their logic.
if ( !isGenerated( dialect ) ) return null;
StringBuilder buf = new StringBuilder(
dialect.getAddUniqueConstraintString( constraintName )
).append( '(' );
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;
return buf.append( ')' ).toString();
}
@Override
@ -97,12 +96,13 @@ public class UniqueKey extends Constraint {
@Override
public boolean isGenerated(Dialect dialect) {
if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) return false;
if ( dialect.supportsNotNullUnique() ) return true;
Iterator iter = getColumnIterator();
while ( iter.hasNext() ) {
if ( ( (Column) iter.next() ).isNullable() ) {
return false;
}
// Dialect does not support "not null unique" and this column is not null.
if ( ! ( (Column) iter.next() ).isNullable() ) return false;
}
return true;
}

View File

@ -199,16 +199,20 @@ public class Table extends AbstractTableSpecification implements Exportable {
}
boolean useUniqueConstraint = col.isUnique() &&
( col.isNullable() || dialect.supportsNotNullUnique() );
if ( useUniqueConstraint ) {
if ( dialect.supportsUnique() ) {
buf.append( " unique" );
}
else {
// If the column is 1.) unique and nullable or 2.) unique,
// not null, and the dialect supports unique not null
if ( col.isUnique()
&& ( col.isNullable()
|| dialect.supportsNotNullUnique() ) ) {
if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
// If the constraint is supported, do not add to the column syntax.
UniqueKey uk = getOrCreateUniqueKey( col.getColumnName().encloseInQuotesIfQuoted( dialect ) + '_' );
uk.addColumn( col );
}
else if ( dialect.supportsUnique() ) {
// Otherwise, add to the column syntax if supported.
buf.append( " unique" );
}
}
if ( col.getCheckCondition() != null && dialect.supportsColumnCheck() ) {

View File

@ -48,21 +48,22 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
@Override
public boolean isCreationVetoed(Dialect dialect) {
if ( dialect.supportsNotNullUnique() ) {
return false;
}
if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) return true;
if ( dialect.supportsNotNullUnique() ) return false;
for ( Column column : getColumns() ) {
if ( column.isNullable() ) {
return true;
}
// Dialect does not support "not null unique" and this column is not null.
if ( ! column.isNullable() ) return true;
}
return false;
}
public String sqlConstraintStringInCreateTable(Dialect dialect) {
// TODO: This may not be necessary, but not all callers currently
// check it on their own. Go through their logic.
if ( isCreationVetoed( dialect ) ) return null;
StringBuilder buf = new StringBuilder( "unique (" );
boolean hadNullableColumn = false;
boolean first = true;
for ( Column column : getColumns() ) {
if ( first ) {
@ -71,23 +72,19 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
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;
return buf.append( ')' ).toString();
}
@Override
public String sqlConstraintStringInAlterTable(Dialect dialect) {
// TODO: This may not be necessary, but not all callers currently
// check it on their own. Go through their logic.
if ( isCreationVetoed( dialect ) ) return null;
StringBuilder buf = new StringBuilder(
dialect.getAddUniqueConstraintString( getName() )
).append( '(' );
boolean nullable = false;
dialect.getAddUniqueConstraintString( getName() ) ).append( '(' );
boolean first = true;
for ( Column column : getColumns() ) {
if ( first ) {
@ -96,11 +93,8 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
else {
buf.append( ", " );
}
if ( !nullable && column.isNullable() ) {
nullable = true;
}
buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) );
}
return !nullable || dialect.supportsNotNullUnique() ? buf.append( ')' ).toString() : null;
return buf.append( ')' ).toString();
}
}