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;
import java.util.Objects;
/**
* Represents a table or column level {@code check} constraint.
*
@ -24,6 +26,14 @@ public class CheckConstraint {
this.constraint = constraint;
}
public boolean isNamed() {
return name != null;
}
public boolean isAnonymous() {
return name == null;
}
public String getName() {
return name;
}
@ -36,6 +46,10 @@ public class CheckConstraint {
return constraint;
}
public String getConstraintInParens() {
return "(" + constraint + ")";
}
public void setConstraint(String constraint) {
this.constraint = constraint;
}
@ -45,4 +59,21 @@ public class CheckConstraint {
? " 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) {
this.checkConstraints.add( checkConstraint );
if ( !checkConstraints.contains( checkConstraint) ) {
checkConstraints.add( checkConstraint );
}
}
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.type.descriptor.jdbc.JdbcType;
import java.util.List;
class ColumnDefinitions {
static boolean hasMatchingType(Column column, ColumnInformation columnInformation, Metadata metadata, Dialect dialect) {
@ -97,13 +99,41 @@ class ColumnDefinitions {
if ( column.isUnique() && !table.isPrimaryKey( column ) ) {
final String keyName = Constraint.generateName( "UK_", table, column);
final UniqueKey uniqueKey = table.getOrCreateUniqueKey( keyName );
uniqueKey.addColumn(column);
uniqueKey.addColumn( column );
definition.append( dialect.getUniqueDelegate().getColumnDefinitionUniquenessFragment( column, context ) );
}
if ( dialect.supportsColumnCheck() ) {
for ( CheckConstraint checkConstraint : column.getCheckConstraints() ) {
definition.append( checkConstraint.constraintString() );
// some databases (Maria, SQL Server) don't like multiple 'check' clauses
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() );
}
}
}
}
}