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; return true;
} }
/**
* Does this dialect support columns that are both unique and not null.
*
* @return True if supported, false otherwise.
*/
public boolean supportsNotNullUnique() { public boolean supportsNotNullUnique() {
return true; return true;
} }

View File

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

View File

@ -35,23 +35,21 @@ import org.hibernate.engine.spi.Mapping;
public class UniqueKey extends Constraint { public class UniqueKey extends Constraint {
public String sqlConstraintString(Dialect dialect) { 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 (" ); StringBuilder buf = new StringBuilder( "unique (" );
boolean hadNullableColumn = false;
Iterator iter = getColumnIterator(); Iterator iter = getColumnIterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
Column column = (Column) iter.next(); Column column = (Column) iter.next();
if ( !hadNullableColumn && column.isNullable() ) {
hadNullableColumn = true;
}
buf.append( column.getQuotedName( dialect ) ); buf.append( column.getQuotedName( dialect ) );
if ( iter.hasNext() ) { if ( iter.hasNext() ) {
buf.append( ", " ); buf.append( ", " );
} }
} }
//do not add unique constraint on DB not supporting unique and nullable columns
return !hadNullableColumn || dialect.supportsNotNullUnique() ? return buf.append( ')' ).toString();
buf.append( ')' ).toString() :
null;
} }
@Override @Override
@ -60,18 +58,19 @@ public class UniqueKey extends Constraint {
String constraintName, String constraintName,
String defaultCatalog, String defaultCatalog,
String defaultSchema) { 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( StringBuilder buf = new StringBuilder(
dialect.getAddUniqueConstraintString( constraintName ) dialect.getAddUniqueConstraintString( constraintName ) ).append( '(' );
).append( '(' );
Iterator iter = getColumnIterator(); Iterator iter = getColumnIterator();
boolean nullable = false;
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
Column column = (Column) iter.next(); Column column = (Column) iter.next();
if ( !nullable && column.isNullable() ) nullable = true;
buf.append( column.getQuotedName( dialect ) ); buf.append( column.getQuotedName( dialect ) );
if ( iter.hasNext() ) buf.append( ", " ); if ( iter.hasNext() ) buf.append( ", " );
} }
return !nullable || dialect.supportsNotNullUnique() ? buf.append( ')' ).toString() : null; return buf.append( ')' ).toString();
} }
@Override @Override
@ -97,12 +96,13 @@ public class UniqueKey extends Constraint {
@Override @Override
public boolean isGenerated(Dialect dialect) { public boolean isGenerated(Dialect dialect) {
if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) return false;
if ( dialect.supportsNotNullUnique() ) return true; if ( dialect.supportsNotNullUnique() ) return true;
Iterator iter = getColumnIterator(); Iterator iter = getColumnIterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
if ( ( (Column) iter.next() ).isNullable() ) { // Dialect does not support "not null unique" and this column is not null.
return false; if ( ! ( (Column) iter.next() ).isNullable() ) return false;
}
} }
return true; return true;
} }

View File

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

View File

@ -48,21 +48,22 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
@Override @Override
public boolean isCreationVetoed(Dialect dialect) { public boolean isCreationVetoed(Dialect dialect) {
if ( dialect.supportsNotNullUnique() ) { if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) return true;
return false; if ( dialect.supportsNotNullUnique() ) return false;
}
for ( Column column : getColumns() ) { for ( Column column : getColumns() ) {
if ( column.isNullable() ) { // Dialect does not support "not null unique" and this column is not null.
return true; if ( ! column.isNullable() ) return true;
}
} }
return false; return false;
} }
public String sqlConstraintStringInCreateTable(Dialect dialect) { 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 (" ); StringBuilder buf = new StringBuilder( "unique (" );
boolean hadNullableColumn = false;
boolean first = true; boolean first = true;
for ( Column column : getColumns() ) { for ( Column column : getColumns() ) {
if ( first ) { if ( first ) {
@ -71,23 +72,19 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
else { else {
buf.append( ", " ); buf.append( ", " );
} }
if ( !hadNullableColumn && column.isNullable() ) {
hadNullableColumn = true;
}
buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) ); buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) );
} }
//do not add unique constraint on DB not supporting unique and nullable columns return buf.append( ')' ).toString();
return !hadNullableColumn || dialect.supportsNotNullUnique() ?
buf.append( ')' ).toString() :
null;
} }
@Override @Override
public String sqlConstraintStringInAlterTable(Dialect dialect) { 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( StringBuilder buf = new StringBuilder(
dialect.getAddUniqueConstraintString( getName() ) dialect.getAddUniqueConstraintString( getName() ) ).append( '(' );
).append( '(' );
boolean nullable = false;
boolean first = true; boolean first = true;
for ( Column column : getColumns() ) { for ( Column column : getColumns() ) {
if ( first ) { if ( first ) {
@ -96,11 +93,8 @@ public class UniqueKey extends AbstractConstraint implements Constraint {
else { else {
buf.append( ", " ); buf.append( ", " );
} }
if ( !nullable && column.isNullable() ) {
nullable = true;
}
buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) ); buf.append( column.getColumnName().encloseInQuotesIfQuoted( dialect ) );
} }
return !nullable || dialect.supportsNotNullUnique() ? buf.append( ')' ).toString() : null; return buf.append( ')' ).toString();
} }
} }