Skip to content

Commit 4791b41

Browse files
committed
HHH-16531 be more forgiving in handling of integral types in schema validation/update
Signed-off-by: Gavin King <gavin@hibernate.org>
1 parent 0f8ef48 commit 4791b41

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,6 +1591,10 @@ public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType,
15911591
* {@link Types#VARBINARY BINARY} and
15921592
* {@link Types#LONGVARBINARY LONGVARBINARY} as the same type, since
15931593
* Hibernate doesn't really differentiate these types.
1594+
* <p>
1595+
* On the other hand, integral types are not treated as equivalent,
1596+
* instead, {@link #isCompatibleIntegralType(int, int)} is responsible
1597+
* for determining if the types are compatible.
15941598
*
15951599
* @param typeCode1 the first column type info
15961600
* @param typeCode2 the second column type info
@@ -1600,16 +1604,39 @@ public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType,
16001604
public boolean equivalentTypes(int typeCode1, int typeCode2) {
16011605
return typeCode1==typeCode2
16021606
|| isNumericOrDecimal(typeCode1) && isNumericOrDecimal(typeCode2)
1603-
// || isIntegral(typeCode1) && isIntegral(typeCode2)
16041607
|| isFloatOrRealOrDouble(typeCode1) && isFloatOrRealOrDouble(typeCode2)
16051608
|| isVarcharType(typeCode1) && isVarcharType(typeCode2)
16061609
|| isVarbinaryType(typeCode1) && isVarbinaryType(typeCode2)
1610+
|| isCompatibleIntegralType(typeCode1, typeCode2)
16071611
// HHH-17908: Since the runtime can cope with enum on the DDL side,
16081612
// but varchar on the ORM expectation side, let's treat the types as equivalent
1609-
|| isEnumType( typeCode1 ) && isVarcharType( typeCode2 )
1613+
|| isEnumType(typeCode1) && isVarcharType(typeCode2)
16101614
|| sameColumnType(typeCode1, typeCode2);
16111615
}
16121616

1617+
/**
1618+
* Tolerate storing {@code short} in {@code INTEGER} or {@code BIGINT}
1619+
* or {@code int} in {@code BIGINT} for the purposes of schema validation
1620+
* and migration.
1621+
*/
1622+
private boolean isCompatibleIntegralType(int typeCode1, int typeCode2) {
1623+
switch (typeCode1) {
1624+
case TINYINT:
1625+
return typeCode2 == TINYINT
1626+
|| typeCode2 == SMALLINT
1627+
|| typeCode2 == INTEGER
1628+
|| typeCode2 == BIGINT;
1629+
case SMALLINT:
1630+
return typeCode2 == SMALLINT
1631+
|| typeCode2 == INTEGER
1632+
|| typeCode2 == BIGINT;
1633+
case INTEGER:
1634+
return typeCode2 == INTEGER
1635+
|| typeCode2 == BIGINT;
1636+
}
1637+
return false;
1638+
}
1639+
16131640
private boolean sameColumnType(int typeCode1, int typeCode2) {
16141641
try {
16151642
return Objects.equals( columnType(typeCode1), columnType(typeCode2) );

hibernate-core/src/main/java/org/hibernate/tool/schema/internal/AbstractSchemaValidator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.jboss.logging.Logger;
3434

3535
import static org.hibernate.boot.model.naming.Identifier.toIdentifier;
36+
import static org.hibernate.tool.schema.internal.ColumnDefinitions.hasMatchingType;
3637

3738
/**
3839
* Base implementation of {@link SchemaValidator}.
@@ -163,7 +164,7 @@ protected void validateColumnType(
163164
Metadata metadata,
164165
ExecutionOptions options,
165166
Dialect dialect) {
166-
if ( !ColumnDefinitions.hasMatchingType( column, columnInformation, metadata, dialect ) ) {
167+
if ( !hasMatchingType( column, columnInformation, metadata, dialect ) ) {
167168
throw new SchemaManagementException(
168169
String.format(
169170
"Schema-validation: wrong column type encountered in column [%s] in " +

hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
class ColumnDefinitions {
2828

2929
static boolean hasMatchingType(Column column, ColumnInformation columnInformation, Metadata metadata, Dialect dialect) {
30-
boolean typesMatch = dialect.equivalentTypes( column.getSqlTypeCode(metadata), columnInformation.getTypeCode() )
30+
final boolean typesMatch = dialect.equivalentTypes( column.getSqlTypeCode( metadata ), columnInformation.getTypeCode() )
3131
|| normalize( stripArgs( column.getSqlType( metadata ) ) ).equals( normalize( columnInformation.getTypeName() ) );
3232
if ( typesMatch ) {
3333
return true;
@@ -42,7 +42,7 @@ static boolean hasMatchingType(Column column, ColumnInformation columnInformatio
4242
columnInformation.getDecimalDigits(),
4343
metadata.getDatabase().getTypeConfiguration().getJdbcTypeRegistry()
4444
);
45-
return dialect.equivalentTypes( column.getSqlTypeCode(metadata), jdbcType.getDefaultSqlTypeCode() );
45+
return dialect.equivalentTypes( column.getSqlTypeCode( metadata ), jdbcType.getDefaultSqlTypeCode() );
4646
}
4747
}
4848

0 commit comments

Comments
 (0)