fix for databases which don't like multiple 'check' keywords

- also check for dupe constraints (for some reason they get added)
This commit is contained in:
Gavin 2023-01-02 20:31:02 +01:00 committed by Gavin King
parent f385fa063a
commit b7f34795df
3 changed files with 67 additions and 4 deletions

View File

@ -6,6 +6,8 @@
*/ */
package org.hibernate.mapping; package org.hibernate.mapping;
import java.util.Objects;
/** /**
* Represents a table or column level {@code check} constraint. * Represents a table or column level {@code check} constraint.
* *
@ -24,6 +26,14 @@ public class CheckConstraint {
this.constraint = constraint; this.constraint = constraint;
} }
public boolean isNamed() {
return name != null;
}
public boolean isAnonymous() {
return name == null;
}
public String getName() { public String getName() {
return name; return name;
} }
@ -36,6 +46,10 @@ public class CheckConstraint {
return constraint; return constraint;
} }
public String getConstraintInParens() {
return "(" + constraint + ")";
}
public void setConstraint(String constraint) { public void setConstraint(String constraint) {
this.constraint = constraint; this.constraint = constraint;
} }
@ -45,4 +59,21 @@ public class CheckConstraint {
? " check (" + constraint + ")" ? " check (" + constraint + ")"
: " constraint " + name + " check (" + constraint + ")"; : " constraint " + name + " check (" + constraint + ")";
} }
@Override
public boolean equals(Object object) {
if ( object instanceof CheckConstraint ) {
CheckConstraint other = (CheckConstraint) object;
return Objects.equals( name, other.name )
&& Objects.equals( constraint, other.constraint );
}
else {
return false;
}
}
@Override
public int hashCode() {
return constraint.hashCode();
}
} }

View File

@ -493,7 +493,9 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
} }
public void addCheckConstraint(CheckConstraint checkConstraint) { public void addCheckConstraint(CheckConstraint checkConstraint) {
this.checkConstraints.add( checkConstraint ); if ( !checkConstraints.contains( checkConstraint) ) {
checkConstraints.add( checkConstraint );
}
} }
public java.util.List<CheckConstraint> getCheckConstraints() { public java.util.List<CheckConstraint> getCheckConstraints() {

View File

@ -19,6 +19,8 @@ import org.hibernate.mapping.UniqueKey;
import org.hibernate.tool.schema.extract.spi.ColumnInformation; import org.hibernate.tool.schema.extract.spi.ColumnInformation;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
import java.util.List;
class ColumnDefinitions { class ColumnDefinitions {
static boolean hasMatchingType(Column column, ColumnInformation columnInformation, Metadata metadata, Dialect dialect) { static boolean hasMatchingType(Column column, ColumnInformation columnInformation, Metadata metadata, Dialect dialect) {
@ -97,13 +99,41 @@ class ColumnDefinitions {
if ( column.isUnique() && !table.isPrimaryKey( column ) ) { if ( column.isUnique() && !table.isPrimaryKey( column ) ) {
final String keyName = Constraint.generateName( "UK_", table, column); final String keyName = Constraint.generateName( "UK_", table, column);
final UniqueKey uniqueKey = table.getOrCreateUniqueKey( keyName ); final UniqueKey uniqueKey = table.getOrCreateUniqueKey( keyName );
uniqueKey.addColumn(column); uniqueKey.addColumn( column );
definition.append( dialect.getUniqueDelegate().getColumnDefinitionUniquenessFragment( column, context ) ); definition.append( dialect.getUniqueDelegate().getColumnDefinitionUniquenessFragment( column, context ) );
} }
if ( dialect.supportsColumnCheck() ) { if ( dialect.supportsColumnCheck() ) {
for ( CheckConstraint checkConstraint : column.getCheckConstraints() ) { // some databases (Maria, SQL Server) don't like multiple 'check' clauses
definition.append( checkConstraint.constraintString() ); final List<CheckConstraint> checkConstraints = column.getCheckConstraints();
long anonConstraints = checkConstraints.stream().filter(CheckConstraint::isAnonymous).count();
if ( anonConstraints == 1 ) {
for ( CheckConstraint constraint : checkConstraints ) {
definition.append( constraint.constraintString() );
}
}
else {
boolean first = true;
for ( CheckConstraint constraint : checkConstraints ) {
if ( constraint.isAnonymous() ) {
if ( first ) {
definition.append(" check (");
first = false;
}
else {
definition.append(" and ");
}
definition.append( constraint.getConstraintInParens() );
}
}
if ( !first ) {
definition.append(")");
}
for ( CheckConstraint constraint : checkConstraints ) {
if ( constraint.isNamed() ) {
definition.append( constraint.constraintString() );
}
}
} }
} }
} }