diff --git a/gradle/databases.gradle b/gradle/databases.gradle index 65f0123548..f97dadd084 100644 --- a/gradle/databases.gradle +++ b/gradle/databases.gradle @@ -174,7 +174,7 @@ ext { // // To avoid hibernate-spatial tests failure, JVM must be enabled as stated in documentation: // https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/autonomous-oracle-java.html - 'jdbc.url' : 'jdbc:oracle:thin:@(description=(retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=' + dbHost + '.oraclecloud.com))(connect_data=(service_name=' + dbService + '_tp.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))', + 'jdbc.url' : 'jdbc:oracle:thin:@(description=(retry_count=5)(retry_delay=1)(address=(protocol=tcps)(port=1521)(host=' + dbHost + '.oraclecloud.com))(connect_data=(service_name=' + dbService + '_tp.adb.oraclecloud.com))(security=(ssl_server_dn_match=no)))?oracle.jdbc.enableQueryResultCache=false&oracle.jdbc.thinForceDNSLoadBalancing=true&tcp.nodelay=yes', 'connection.init_sql' : '' ], oracle_cloud_db19c : [ diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDDialect.java index 13ca6a723e..d73897a57a 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDDialect.java @@ -106,7 +106,12 @@ public class CUBRIDDialect extends Dialect { //length parameter is measured in bits, not bytes) ddlTypeRegistry.addDescriptor( new DdlTypeImpl( BINARY, "bit($l)", this ) ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( VARBINARY, columnType( BLOB ), this ) + CapacityDependentDdlType.builder( + VARBINARY, + CapacityDependentDdlType.LobKind.BIGGEST_LOB, + columnType( BLOB ), + this + ) .withTypeCapacity( getMaxVarbinaryLength(), "bit varying($l)" ) .build() ); diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacyDialect.java index 48ea03c1e4..0125723c42 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacyDialect.java @@ -185,23 +185,55 @@ public class DerbyLegacyDialect extends Dialect { int varcharDdlTypeCapacity = 32_672; ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( VARBINARY, columnType( LONG32VARBINARY ), columnType( VARBINARY ), this ) + CapacityDependentDdlType.builder( + VARBINARY, + isLob( LONG32VARBINARY ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARBINARY ), + columnType( VARBINARY ), + this + ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) ) .build() ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( VARCHAR, columnType( LONG32VARCHAR ), columnType( VARCHAR ), this ) + CapacityDependentDdlType.builder( + VARCHAR, + isLob( LONG32VARCHAR ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARCHAR ), + columnType( VARCHAR ), + this + ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARCHAR ) ) .build() ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( NVARCHAR, columnType( LONG32VARCHAR ), columnType( NVARCHAR ), this ) + CapacityDependentDdlType.builder( + NVARCHAR, + isLob( LONG32NVARCHAR ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARCHAR ), + columnType( NVARCHAR ), + this + ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( NVARCHAR ) ) .build() ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( BINARY, columnType( LONG32VARBINARY ), columnType( VARBINARY ), this ) + CapacityDependentDdlType.builder( + BINARY, + isLob( LONG32VARBINARY ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARBINARY ), + columnType( VARBINARY ), + this + ) .withTypeCapacity( 254, "char($l) for bit data" ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) ) .build() @@ -209,13 +241,29 @@ public class DerbyLegacyDialect extends Dialect { // This is the maximum size for the CHAR datatype on Derby ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( CHAR, columnType( LONG32VARCHAR ), columnType( CHAR ), this ) + CapacityDependentDdlType.builder( + CHAR, + isLob( LONG32VARCHAR ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARCHAR ), + columnType( CHAR ), + this + ) .withTypeCapacity( 254, columnType( CHAR ) ) .withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) ) .build() ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( NCHAR, columnType( LONG32NVARCHAR ), columnType( NCHAR ), this ) + CapacityDependentDdlType.builder( + NCHAR, + isLob( LONG32NVARCHAR ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32NVARCHAR ), + columnType( NCHAR ), + this + ) .withTypeCapacity( 254, columnType( NCHAR ) ) .withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) ) .build() diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLDialect.java index 44ce68c3c5..65eb290918 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLDialect.java @@ -42,6 +42,7 @@ import static org.hibernate.type.SqlTypes.BLOB; import static org.hibernate.type.SqlTypes.CHAR; import static org.hibernate.type.SqlTypes.CLOB; import static org.hibernate.type.SqlTypes.LONG32NVARCHAR; +import static org.hibernate.type.SqlTypes.LONG32VARBINARY; import static org.hibernate.type.SqlTypes.LONG32VARCHAR; import static org.hibernate.type.SqlTypes.NCHAR; import static org.hibernate.type.SqlTypes.NCLOB; @@ -113,7 +114,15 @@ public class MimerSQLDialect extends Dialect { //Mimer CHARs are ASCII!! ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( VARCHAR, columnType( LONG32VARCHAR ), "nvarchar(" + getMaxNVarcharLength() + ")", this ) + CapacityDependentDdlType.builder( + VARCHAR, + isLob( LONG32VARCHAR ) ? + CapacityDependentDdlType.LobKind.BIGGEST_LOB : + CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARCHAR ), + "nvarchar(" + getMaxNVarcharLength() + ")", + this + ) .withTypeCapacity( getMaxNVarcharLength(), columnType( VARCHAR ) ) .build() ); diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java index edd4c6b985..9e99f03254 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java @@ -311,7 +311,7 @@ public class MySQLLegacyDialect extends Dialect { final CapacityDependentDdlType.Builder varcharBuilder = CapacityDependentDdlType.builder( VARCHAR, - columnType( CLOB ), + CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( CLOB ), "char", this ) @@ -324,7 +324,7 @@ public class MySQLLegacyDialect extends Dialect { final CapacityDependentDdlType.Builder nvarcharBuilder = CapacityDependentDdlType.builder( NVARCHAR, - columnType( NCLOB ), + CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( NCLOB ), "char", this ) @@ -337,7 +337,7 @@ public class MySQLLegacyDialect extends Dialect { final CapacityDependentDdlType.Builder varbinaryBuilder = CapacityDependentDdlType.builder( VARBINARY, - columnType( BLOB ), + CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( BLOB ), "binary", this ) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java index 38187045bf..7adf8cc25e 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java @@ -300,7 +300,7 @@ public abstract class AbstractHANADialect extends Dialect { // varbinary max length 5000 ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( BINARY, "blob", this ) + CapacityDependentDdlType.builder( BINARY, CapacityDependentDdlType.LobKind.BIGGEST_LOB, "blob", this ) .withTypeCapacity( getMaxVarbinaryLength(), "varbinary($l)" ) .build() ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DerbyDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DerbyDialect.java index c862b24103..16c59dc25f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DerbyDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DerbyDialect.java @@ -182,23 +182,55 @@ public class DerbyDialect extends Dialect { int varcharDdlTypeCapacity = 32_672; ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( VARBINARY, columnType( LONG32VARBINARY ), columnType( VARBINARY ), this ) + CapacityDependentDdlType.builder( + VARBINARY, + isLob( LONG32VARBINARY ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARBINARY ), + columnType( VARBINARY ), + this + ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) ) .build() ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( VARCHAR, columnType( LONG32VARCHAR ), columnType( VARCHAR ), this ) + CapacityDependentDdlType.builder( + VARCHAR, + isLob( LONG32VARCHAR ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARCHAR ), + columnType( VARCHAR ), + this + ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARCHAR ) ) .build() ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( NVARCHAR, columnType( LONG32VARCHAR ), columnType( NVARCHAR ), this ) + CapacityDependentDdlType.builder( + NVARCHAR, + isLob( LONG32NVARCHAR ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARCHAR ), + columnType( NVARCHAR ), + this + ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( NVARCHAR ) ) .build() ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( BINARY, columnType( LONG32VARBINARY ), columnType( VARBINARY ), this ) + CapacityDependentDdlType.builder( + BINARY, + isLob( LONG32VARBINARY ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARBINARY ), + columnType( VARBINARY ), + this + ) .withTypeCapacity( 254, "char($l) for bit data" ) .withTypeCapacity( varcharDdlTypeCapacity, columnType( VARBINARY ) ) .build() @@ -206,13 +238,29 @@ public class DerbyDialect extends Dialect { // This is the maximum size for the CHAR datatype on Derby ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( CHAR, columnType( LONG32VARCHAR ), columnType( CHAR ), this ) + CapacityDependentDdlType.builder( + CHAR, + isLob( LONG32VARCHAR ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32VARCHAR ), + columnType( CHAR ), + this + ) .withTypeCapacity( 254, columnType( CHAR ) ) .withTypeCapacity( getMaxVarcharLength(), columnType( VARCHAR ) ) .build() ); ddlTypeRegistry.addDescriptor( - CapacityDependentDdlType.builder( NCHAR, columnType( LONG32NVARCHAR ), columnType( NCHAR ), this ) + CapacityDependentDdlType.builder( + NCHAR, + isLob( LONG32NVARCHAR ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, + columnType( LONG32NVARCHAR ), + columnType( NCHAR ), + this + ) .withTypeCapacity( 254, columnType( NCHAR ) ) .withTypeCapacity( getMaxVarcharLength(), columnType( NVARCHAR ) ) .build() diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 1dfc5fbf69..ef39715c67 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -440,10 +440,34 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32VARCHAR ) ); ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32NVARCHAR ) ); ddlTypeRegistry.addDescriptor( simpleSqlType( LONG32VARBINARY ) ); + + if ( rowId( null ) != null ) { + ddlTypeRegistry.addDescriptor( simpleSqlType( ROWID ) ); + } + } + + protected boolean isLob(int sqlTypeCode) { + switch ( sqlTypeCode ) { + case LONG32VARBINARY: + case LONG32VARCHAR: + case LONG32NVARCHAR: + case BLOB: + case CLOB: + case NCLOB: + return true; + default: + return false; + } } private DdlTypeImpl simpleSqlType(int sqlTypeCode) { - return new DdlTypeImpl( sqlTypeCode, columnType( sqlTypeCode ), castType( sqlTypeCode ), this ); + return new DdlTypeImpl( + sqlTypeCode, + isLob( sqlTypeCode ), + columnType( sqlTypeCode ), + castType( sqlTypeCode ), + this + ); } /** @@ -457,6 +481,11 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun private CapacityDependentDdlType.Builder sqlTypeBuilder(int sqlTypeCode, int biggestSqlTypeCode, int castTypeCode) { return CapacityDependentDdlType.builder( sqlTypeCode, + isLob( sqlTypeCode ) + ? CapacityDependentDdlType.LobKind.ALL_LOB + : isLob( biggestSqlTypeCode ) + ? CapacityDependentDdlType.LobKind.BIGGEST_LOB + : CapacityDependentDdlType.LobKind.NONE, columnType( biggestSqlTypeCode ), castType( castTypeCode ), this @@ -504,6 +533,9 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun */ protected String columnType(int sqlTypeCode) { switch ( sqlTypeCode ) { + case ROWID: + return "rowid"; + case BOOLEAN: return "boolean"; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java index be5fd42a1c..bdb5ab7873 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java @@ -316,7 +316,7 @@ public class MySQLDialect extends Dialect { final CapacityDependentDdlType.Builder varcharBuilder = CapacityDependentDdlType.builder( VARCHAR, - columnType( CLOB ), + CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( CLOB ), "char", this ) @@ -329,7 +329,7 @@ public class MySQLDialect extends Dialect { final CapacityDependentDdlType.Builder nvarcharBuilder = CapacityDependentDdlType.builder( NVARCHAR, - columnType( NCLOB ), + CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( NCLOB ), "char", this ) @@ -342,7 +342,7 @@ public class MySQLDialect extends Dialect { final CapacityDependentDdlType.Builder varbinaryBuilder = CapacityDependentDdlType.builder( VARBINARY, - columnType( BLOB ), + CapacityDependentDdlType.LobKind.BIGGEST_LOB,columnType( BLOB ), "binary", this ) diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Column.java b/hibernate-core/src/main/java/org/hibernate/mapping/Column.java index dde3b634d3..6311427894 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Column.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Column.java @@ -31,6 +31,8 @@ import org.hibernate.type.ComponentType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; import org.hibernate.type.descriptor.jdbc.ArrayJdbcType; +import org.hibernate.type.descriptor.JdbcTypeNameMapper; +import org.hibernate.type.descriptor.sql.DdlType; import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry; import org.hibernate.type.spi.TypeConfiguration; @@ -58,6 +60,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn private boolean unique; private String sqlTypeName; private Integer sqlTypeCode; + private boolean sqlTypeLob; private boolean quoted; int uniqueInteger; private String comment; @@ -270,11 +273,34 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn private String getSqlTypeName(DdlTypeRegistry ddlTypeRegistry, Dialect dialect, Mapping mapping) { if ( sqlTypeName == null ) { + final Type type = getValue().getType(); try { - final Type type = getValue().getType(); - sqlTypeName = isArray( type ) - ? dialect.getArrayTypeName( getArrayElementTypeName( dialect, ddlTypeRegistry, getArrayElementType( type ) ) ) - : ddlTypeRegistry.getTypeName( getSqlTypeCode( mapping ), getColumnSize( dialect, mapping ) ); + if ( isArray( type ) ) { + sqlTypeName = dialect.getArrayTypeName( getArrayElementTypeName( dialect, ddlTypeRegistry, getArrayElementType( type ) ) ); + sqlTypeLob = false; + } + else { + final int typeCode = getSqlTypeCode( mapping ); + final DdlType descriptor = ddlTypeRegistry.getDescriptor( typeCode ); + if ( descriptor == null ) { + throw new MappingException( + String.format( + Locale.ROOT, + "Unable to determine SQL type name for column '%s' of table '%s' because there is no type mapping for org.hibernate.type.SqlTypes code: %s (%s)", + getName(), + getValue().getTable().getName(), + typeCode, + JdbcTypeNameMapper.getTypeName( typeCode ) + ) + ); + } + final Size size = getColumnSize( dialect, mapping ); + sqlTypeName = ddlTypeRegistry.getTypeName( typeCode, size ); + sqlTypeLob = descriptor.isLob( size ); + } + } + catch ( MappingException cause ) { + throw cause; } catch ( Exception cause ) { throw new MappingException( @@ -467,6 +493,10 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn sqlTypeName = typeName; } + public boolean isSqlTypeLob() { + return sqlTypeLob; + } + public void setUnique(boolean unique) { this.unique = unique; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SqlTypedMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SqlTypedMapping.java index 3ac8245d7d..6e6f9475cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SqlTypedMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SqlTypedMapping.java @@ -16,5 +16,8 @@ public interface SqlTypedMapping { Long getLength(); Integer getPrecision(); Integer getScale(); + default boolean isLob() { + return getJdbcMapping().getJdbcType().isLob(); + } JdbcMapping getJdbcMapping(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java index b4f1ab0b3b..2dfe0054ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java @@ -283,14 +283,16 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType final Long length; final Integer precision; final Integer scale; + final boolean isLob; final boolean nullable; if ( selectable instanceof Column ) { final Column column = (Column) selectable; - columnDefinition = column.getSqlType(); + columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() ); length = column.getLength(); precision = column.getPrecision(); scale = column.getScale(); nullable = column.isNullable(); + isLob = column.isSqlTypeLob(); selectablePath = basicValue.createSelectablePath( column.getQuotedName( dialect ) ); } else { @@ -299,6 +301,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType precision = null; scale = null; nullable = true; + isLob = false; selectablePath = basicValue.createSelectablePath( bootPropertyDescriptor.getName() ); } @@ -320,6 +323,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType length, precision, scale, + isLob, nullable, value.isColumnInsertable( 0 ), value.isColumnUpdateable( 0 ), diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicAttributeMapping.java index 40ee2a194d..980ecb6a7b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/BasicAttributeMapping.java @@ -60,6 +60,7 @@ public class BasicAttributeMapping private final Integer scale; private final JdbcMapping jdbcMapping; + private final boolean isLob; private final boolean nullable; private final boolean insertable; private final boolean updateable; @@ -85,6 +86,7 @@ public class BasicAttributeMapping Long length, Integer precision, Integer scale, + boolean isLob, boolean nullable, boolean insertable, boolean updateable, @@ -116,6 +118,7 @@ public class BasicAttributeMapping this.length = length; this.precision = precision; this.scale = scale; + this.isLob = isLob; this.nullable = nullable; this.insertable = insertable; this.updateable = updateable; @@ -183,6 +186,7 @@ public class BasicAttributeMapping selectableMapping.getLength(), selectableMapping.getPrecision(), selectableMapping.getScale(), + selectableMapping.isLob(), selectableMapping.isNullable(), insertable, updateable, @@ -223,6 +227,11 @@ public class BasicAttributeMapping return selectablePath; } + @Override + public boolean isLob() { + return isLob; + } + @Override public boolean isFormula() { return isFormula; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java index d3eee281b3..5f0a617922 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java @@ -87,7 +87,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption declaringModelPart, tableName, metaColumn.getText( dialect ), - metaColumn.getSqlType(), + metaColumn.getSqlType( creationProcess.getCreationContext().getMetadata() ), metaColumn.getLength(), metaColumn.getPrecision(), metaColumn.getScale(), @@ -106,7 +106,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption declaringModelPart, tableName, keyColumn.getText( dialect ), - keyColumn.getSqlType(), + keyColumn.getSqlType( creationProcess.getCreationContext().getMetadata() ), keyColumn.getLength(), keyColumn.getPrecision(), keyColumn.getScale(), diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java index a93d43dfba..b4f8a5cb88 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java @@ -193,7 +193,8 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme updatable, false, dialect, - null + null, + creationContext ); final AggregateSupport aggregateSupport = dialect.getAggregateSupport(); final int sqlTypeCode = aggregateColumn.getSqlTypeCode(); @@ -227,7 +228,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme typeConfiguration.getJdbcTypeRegistry().resolveAggregateDescriptor( aggregateColumn.getSqlTypeCode(), aggregateColumn.getSqlTypeCode() == SqlTypes.STRUCT - ? aggregateColumn.getSqlType() + ? aggregateColumn.getSqlType( creationContext.getMetadata() ) : null, this, creationContext @@ -378,13 +379,15 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme final Long length; final Integer precision; final Integer scale; + final boolean isLob; final boolean nullable; if ( selectable instanceof Column ) { final Column column = (Column) selectable; - columnDefinition = column.getSqlType(); + columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() ); length = column.getLength(); precision = column.getPrecision(); scale = column.getScale(); + isLob = column.isSqlTypeLob(); nullable = bootPropertyDescriptor.isOptional() && column.isNullable() ; selectablePath = basicValue.createSelectablePath( column.getQuotedName( dialect ) ); } @@ -393,6 +396,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme length = null; precision = null; scale = null; + isLob = false; nullable = bootPropertyDescriptor.isOptional(); selectablePath = basicValue.createSelectablePath( bootPropertyDescriptor.getName() ); } @@ -414,6 +418,7 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme length, precision, scale, + isLob, nullable, insertability[columnPosition], updateability[columnPosition], diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ManyToManyCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ManyToManyCollectionPart.java index 3e24dab83c..7374c743f1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ManyToManyCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ManyToManyCollectionPart.java @@ -502,7 +502,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple false, false, creationProcess.getCreationContext().getDialect(), - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); final BasicAttributeMapping keyModelPart = BasicAttributeMapping.withSelectableMapping( @@ -538,7 +539,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple elementBootDescriptor.getColumnInsertability(), elementBootDescriptor.getColumnUpdateability(), creationProcess.getCreationContext().getDialect(), - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); return new EmbeddedForeignKeyDescriptor( @@ -676,7 +678,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple fkBootDescriptorSource.getColumnInsertability(), fkBootDescriptorSource.getColumnUpdateability(), creationProcess.getCreationContext().getDialect(), - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); return foreignKeyDescriptor.withKeySelectionMapping( declaringType, @@ -718,7 +721,8 @@ public class ManyToManyCollectionPart extends AbstractEntityCollectionPart imple columnUpdateable, fkValue.isPartitionKey(), dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); // here we build a ModelPart that represents the many-to-many table key referring to the element table diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java index 57a163d92c..5b5c4e3dee 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/MappingModelCreationHelper.java @@ -194,6 +194,7 @@ public class MappingModelCreationHelper { Long length, Integer precision, Integer scale, + boolean isLob, boolean nullable, boolean insertable, boolean updateable, @@ -240,6 +241,7 @@ public class MappingModelCreationHelper { length, precision, scale, + isLob, nullable, insertable, updateable, @@ -509,7 +511,8 @@ public class MappingModelCreationHelper { index.isColumnUpdateable( 0 ), false, dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); indexDescriptor = new BasicValuedCollectionPart( collectionDescriptor, @@ -562,7 +565,8 @@ public class MappingModelCreationHelper { index.isColumnUpdateable( 0 ), false, dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); indexDescriptor = new BasicValuedCollectionPart( collectionDescriptor, @@ -773,7 +777,8 @@ public class MappingModelCreationHelper { bootValueMappingKey.isColumnUpdateable( 0 ), false, dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); final SimpleForeignKeyDescriptor keyDescriptor = new SimpleForeignKeyDescriptor( @@ -949,7 +954,8 @@ public class MappingModelCreationHelper { value.isColumnUpdateable( i ), ((SimpleValue) value).isPartitionKey(), dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); i++; } @@ -964,7 +970,8 @@ public class MappingModelCreationHelper { value.isColumnUpdateable( 0 ), ((SimpleValue) value).isPartitionKey(), dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); } @@ -1111,7 +1118,8 @@ public class MappingModelCreationHelper { insertable, updateable, dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); } else { @@ -1135,7 +1143,8 @@ public class MappingModelCreationHelper { insertable, updateable, dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); } if ( inverse ) { @@ -1315,7 +1324,8 @@ public class MappingModelCreationHelper { updatable, false, dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); return new BasicValuedCollectionPart( collectionDescriptor, @@ -1412,7 +1422,8 @@ public class MappingModelCreationHelper { basicElement.isPartitionKey(), true, // element collection does not support null elements dialect, - creationProcess.getSqmFunctionRegistry() + creationProcess.getSqmFunctionRegistry(), + creationProcess.getCreationContext() ); return new BasicValuedCollectionPart( collectionDescriptor, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SelectableMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SelectableMappingImpl.java index f319cc7864..34cd94d37b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SelectableMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SelectableMappingImpl.java @@ -14,6 +14,7 @@ import org.hibernate.mapping.Selectable; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.SelectablePath; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.type.spi.TypeConfiguration; @@ -27,6 +28,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select private final SelectablePath selectablePath; private final String customReadExpression; private final String customWriteExpression; + private final boolean isLob; private final boolean nullable; private final boolean insertable; private final boolean updateable; @@ -43,6 +45,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select Long length, Integer precision, Integer scale, + boolean isLob, boolean nullable, boolean insertable, boolean updateable, @@ -57,6 +60,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select this.selectablePath = selectablePath == null ? new SelectablePath( selectionExpression ) : selectablePath; this.customReadExpression = customReadExpression == null ? null : customReadExpression.intern(); this.customWriteExpression = customWriteExpression == null || isFormula ? null : customWriteExpression.intern(); + this.isLob = isLob; this.nullable = nullable; this.insertable = insertable; this.updateable = updateable; @@ -73,7 +77,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select boolean updateable, boolean partitioned, final Dialect dialect, - final SqmFunctionRegistry sqmFunctionRegistry) { + final SqmFunctionRegistry sqmFunctionRegistry, + RuntimeModelCreationContext creationContext) { return from( containingTableExpression, selectable, @@ -84,7 +89,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select updateable, partitioned, dialect, - sqmFunctionRegistry + sqmFunctionRegistry, + creationContext ); } @@ -98,7 +104,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select boolean partitioned, boolean forceNotNullable, final Dialect dialect, - final SqmFunctionRegistry sqmFunctionRegistry) { + final SqmFunctionRegistry sqmFunctionRegistry, + RuntimeModelCreationContext creationContext) { return from( containingTableExpression, selectable, @@ -110,7 +117,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select partitioned, forceNotNullable, dialect, - sqmFunctionRegistry + sqmFunctionRegistry, + creationContext ); } @@ -124,7 +132,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select boolean updateable, boolean partitioned, final Dialect dialect, - final SqmFunctionRegistry sqmFunctionRegistry) { + final SqmFunctionRegistry sqmFunctionRegistry, + RuntimeModelCreationContext creationContext) { return from( containingTableExpression, selectable, @@ -136,7 +145,8 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select partitioned, false, dialect, - sqmFunctionRegistry + sqmFunctionRegistry, + creationContext ); } @@ -151,13 +161,15 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select boolean partitioned, boolean forceNotNullable, final Dialect dialect, - final SqmFunctionRegistry sqmFunctionRegistry) { + final SqmFunctionRegistry sqmFunctionRegistry, + RuntimeModelCreationContext creationContext) { final String columnExpression; final String columnDefinition; final Long length; final Integer precision; final Integer scale; final String selectableName; + final boolean isLob; final boolean isNullable; if ( selectable.isFormula() ) { columnExpression = selectable.getTemplate( dialect, typeConfiguration, sqmFunctionRegistry ); @@ -166,17 +178,19 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select precision = null; scale = null; isNullable = true; + isLob = false; selectableName = selectable.getText(); } else { Column column = (Column) selectable; columnExpression = selectable.getText( dialect ); - columnDefinition = column.getSqlType(); + columnDefinition = column.getSqlType( creationContext.getMetadata() ); length = column.getLength(); precision = column.getPrecision(); scale = column.getScale(); isNullable = forceNotNullable ? false : column.isNullable(); + isLob = column.isSqlTypeLob(); selectableName = column.getQuotedName( dialect ); } return new SelectableMappingImpl( @@ -191,6 +205,7 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select length, precision, scale, + isLob, isNullable, insertable, updateable, @@ -245,6 +260,11 @@ public class SelectableMappingImpl extends SqlTypedMappingImpl implements Select return customWriteExpression; } + @Override + public boolean isLob() { + return isLob; + } + @Override public boolean isFormula() { return isFormula; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SelectableMappingsImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SelectableMappingsImpl.java index 55e8712066..7ff282dd78 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SelectableMappingsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SelectableMappingsImpl.java @@ -19,6 +19,7 @@ import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.SelectableConsumer; import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.SelectableMappings; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; @@ -64,7 +65,8 @@ public class SelectableMappingsImpl implements SelectableMappings { boolean[] insertable, boolean[] updateable, Dialect dialect, - SqmFunctionRegistry sqmFunctionRegistry) { + SqmFunctionRegistry sqmFunctionRegistry, + RuntimeModelCreationContext creationContext) { if ( insertable.length == 0 ) { return from( containingTableExpression, @@ -73,7 +75,8 @@ public class SelectableMappingsImpl implements SelectableMappings { mapping, typeConfiguration, dialect, - sqmFunctionRegistry + sqmFunctionRegistry, + creationContext ); } final List jdbcMappings = new ArrayList<>(); @@ -92,7 +95,8 @@ public class SelectableMappingsImpl implements SelectableMappings { updateable[i], false, dialect, - sqmFunctionRegistry + sqmFunctionRegistry, + creationContext ); } @@ -106,7 +110,8 @@ public class SelectableMappingsImpl implements SelectableMappings { Mapping mapping, TypeConfiguration typeConfiguration, Dialect dialect, - SqmFunctionRegistry sqmFunctionRegistry) { + SqmFunctionRegistry sqmFunctionRegistry, + RuntimeModelCreationContext creationContext) { final List jdbcMappings = new ArrayList<>(); resolveJdbcMappings( jdbcMappings, mapping, value.getType() ); @@ -123,7 +128,8 @@ public class SelectableMappingsImpl implements SelectableMappings { false, false, dialect, - sqmFunctionRegistry + sqmFunctionRegistry, + creationContext ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java index fc9b59b2b3..bffcab3e68 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java @@ -551,7 +551,8 @@ public class OneToManyPersister extends AbstractCollectionPersister { updateBuilder.addValueColumn( selectable.getSelectionExpression(), NULL, - selectable.getJdbcMapping() + selectable.getJdbcMapping(), + selectable.isLob() ); } @@ -574,7 +575,8 @@ public class OneToManyPersister extends AbstractCollectionPersister { updateBuilder.addValueColumn( selectable.getSelectionExpression(), NULL, - selectable.getJdbcMapping() + selectable.getJdbcMapping(), + selectable.isLob() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 7b79e781c4..46e9df08b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -5037,7 +5037,7 @@ public abstract class AbstractEntityPersister scale = null; } else { - columnDefinition = column.getSqlType(); + columnDefinition = column.getSqlType( modelCreationProcess.getCreationContext().getMetadata() ); length = column.getLength(); precision = column.getPrecision(); scale = column.getScale(); @@ -5214,7 +5214,7 @@ public abstract class AbstractEntityPersister } else { Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 ); - columnDefinition = column.getSqlType(); + columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() ); length = column.getLength(); precision = column.getPrecision(); scale = column.getScale(); @@ -5273,7 +5273,7 @@ public abstract class AbstractEntityPersister bootModelRootEntityDescriptor.getVersion().getName(), entityPersister.getTableName(), column.getText( dialect ), - column.getSqlType(), + column.getSqlType( creationProcess.getCreationContext().getMetadata() ), column.getLength(), column.getPrecision(), column.getScale(), @@ -5318,10 +5318,11 @@ public abstract class AbstractEntityPersister false, null, "?", - column.getSqlType(), + column.getSqlType( creationProcess.getCreationContext().getMetadata() ), column.getLength(), column.getPrecision(), column.getScale(), + column.isSqlTypeLob(), column.isNullable(), value.isColumnInsertable( 0 ), value.isColumnUpdateable( 0 ), @@ -5340,6 +5341,7 @@ public abstract class AbstractEntityPersister final Long length; final Integer precision; final Integer scale; + final boolean isLob; final boolean nullable; if ( value instanceof DependantValue ) { @@ -5348,10 +5350,11 @@ public abstract class AbstractEntityPersister customReadExpr = null; customWriteExpr = "?"; Column column = value.getColumns().get( 0 ); - columnDefinition = column.getSqlType(); + columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() ); length = column.getLength(); precision = column.getPrecision(); scale = column.getScale(); + isLob = column.isSqlTypeLob(); nullable = column.isNullable(); } else { @@ -5374,11 +5377,12 @@ public abstract class AbstractEntityPersister ); customWriteExpr = selectable.getWriteExpr( (JdbcMapping) attrType, creationContext.getDialect() ); Column column = value.getColumns().get( 0 ); - columnDefinition = column.getSqlType(); + columnDefinition = column.getSqlType( creationContext.getMetadata() ); length = column.getLength(); precision = column.getPrecision(); scale = column.getScale(); nullable = column.isNullable(); + isLob = column.isSqlTypeLob(); } else { final String[] attrColumnFormulaTemplate = propertyColumnFormulaTemplates[ propertyIndex ]; @@ -5391,6 +5395,7 @@ public abstract class AbstractEntityPersister precision = null; scale = null; nullable = true; + isLob = false; } } @@ -5412,6 +5417,7 @@ public abstract class AbstractEntityPersister length, precision, scale, + isLob, nullable, value.isColumnInsertable( 0 ), value.isColumnUpdateable( 0 ), diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java index dba24f4be5..977391b564 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java @@ -1186,7 +1186,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { } else { final Column column = bootEntityDescriptor.getIdentifier().getColumns().get( 0 ); - columnDefinition = column.getSqlType(); + columnDefinition = column.getSqlType( creationProcess.getCreationContext().getMetadata() ); length = column.getLength(); precision = column.getPrecision(); scale = column.getScale(); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java index a8b3a9e87e..56942cf85f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java @@ -129,7 +129,8 @@ public abstract class AbstractMutationCoordinator { tableUpdateBuilder.addValueColumn( mapping.getSelectionExpression(), writePropertyValue ? "?" : columnValues[j], - mapping.getJdbcMapping() + mapping.getJdbcMapping(), + mapping.isLob() ); } ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/AbstractTableInsertBuilder.java b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/AbstractTableInsertBuilder.java index 7d64e4d94e..47d8f10491 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/AbstractTableInsertBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/AbstractTableInsertBuilder.java @@ -70,10 +70,10 @@ public abstract class AbstractTableInsertBuilder } @Override - public void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping) { + public void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping, boolean isLob) { final ColumnValueBinding valueBinding = createValueBinding( columnName, columnWriteFragment, jdbcMapping ); - if ( jdbcMapping.getJdbcType().isLob() && getJdbcServices().getDialect().forceLobAsLastValue() ) { + if ( isLob && getJdbcServices().getDialect().forceLobAsLastValue() ) { if ( lobValueBindingList == null ) { lobValueBindingList = new ArrayList<>(); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/AbstractTableUpdateBuilder.java b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/AbstractTableUpdateBuilder.java index 4bade25276..6bd54b6522 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/AbstractTableUpdateBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/AbstractTableUpdateBuilder.java @@ -90,10 +90,11 @@ public abstract class AbstractTableUpdateBuilder public void addValueColumn( String columnName, String columnWriteFragment, - JdbcMapping jdbcMapping) { + JdbcMapping jdbcMapping, + boolean isLob) { final ColumnValueBinding valueBinding = createValueBinding( columnName, columnWriteFragment, jdbcMapping ); - if ( jdbcMapping.getJdbcType().isLob() && getJdbcServices().getDialect().forceLobAsLastValue() ) { + if ( isLob && getJdbcServices().getDialect().forceLobAsLastValue() ) { if ( lobValueBindings == null ) { lobValueBindings = new ArrayList<>(); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/ColumnValuesTableMutationBuilder.java b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/ColumnValuesTableMutationBuilder.java index b7d73db018..d7ce9a6864 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/ColumnValuesTableMutationBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/ColumnValuesTableMutationBuilder.java @@ -19,7 +19,13 @@ public interface ColumnValuesTableMutationBuilder { /** * Add a column as part of the values list */ - void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping); + void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping, boolean isLob); + /** + * Add a column as part of the values list + */ + default void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping) { + addValueColumn( columnName, columnWriteFragment, jdbcMapping, jdbcMapping.getJdbcType().isLob() ); + } /** * Add a column as part of the values list @@ -28,7 +34,8 @@ public interface ColumnValuesTableMutationBuilder { addValueColumn( selectableMapping.getSelectionExpression(), selectableMapping.getWriteExpression(), - selectableMapping.getJdbcMapping() + selectableMapping.getJdbcMapping(), + selectableMapping.isLob() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/TableUpdateBuilderSkipped.java b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/TableUpdateBuilderSkipped.java index 0027e4c3af..6fdd69a968 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/TableUpdateBuilderSkipped.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/TableUpdateBuilderSkipped.java @@ -64,7 +64,7 @@ public class TableUpdateBuilderSkipped implements TableUpdateBuilder { } @Override - public void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping) { + public void addValueColumn(String columnName, String columnWriteFragment, JdbcMapping jdbcMapping, boolean isLob) { // nothing to do } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JdbcType.java index dd64edc7e5..39944d6c76 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JdbcType.java @@ -238,6 +238,24 @@ public interface JdbcType extends Serializable { return false; } + default boolean isLobOrLong() { + return isLobOrLong( getDdlTypeCode() ); + } + + static boolean isLobOrLong(int jdbcTypeCode) { + switch ( jdbcTypeCode ) { + case BLOB: + case CLOB: + case NCLOB: + case LONG32VARBINARY: + case LONG32VARCHAR: + case LONG32NVARCHAR: { + return true; + } + } + return false; + } + default boolean isNationalized() { return isNationalized( getDdlTypeCode() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/DdlType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/DdlType.java index 710c5b9a92..30668163df 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/DdlType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/DdlType.java @@ -64,6 +64,11 @@ public interface DdlType extends Serializable { */ String getTypeName(Long size, Integer precision, Integer scale); + default boolean isLob(Size size) { + // Let's be defensive and assume that LONG32 are LOBs as well + return JdbcType.isLobOrLong( getSqlTypeCode() ); + } + /** * Return the database type corresponding to the given {@link JdbcType} * that may be used as a target type in casting operations using the SQL diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/CapacityDependentDdlType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/CapacityDependentDdlType.java index a033a76160..61aa89114a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/CapacityDependentDdlType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/CapacityDependentDdlType.java @@ -11,6 +11,8 @@ import java.util.Comparator; import java.util.List; import org.hibernate.dialect.Dialect; +import org.hibernate.engine.jdbc.Size; +import org.hibernate.type.descriptor.jdbc.JdbcType; /** * Descriptor for a SQL type. @@ -19,6 +21,7 @@ import org.hibernate.dialect.Dialect; */ public class CapacityDependentDdlType extends DdlTypeImpl { + private final LobKind lobKind; private final TypeEntry[] typeEntries; private CapacityDependentDdlType(Builder builder) { @@ -26,8 +29,10 @@ public class CapacityDependentDdlType extends DdlTypeImpl { builder.sqlTypeCode, builder.typeNamePattern, builder.castTypeNamePattern, + builder.castTypeName, builder.dialect ); + this.lobKind = builder.lobKind; builder.typeEntries.sort( Comparator.naturalOrder() ); this.typeEntries = builder.typeEntries.toArray(new TypeEntry[0]); } @@ -71,33 +76,106 @@ public class CapacityDependentDdlType extends DdlTypeImpl { return super.getTypeName( size, precision, scale ); } + @Override + public boolean isLob(Size size) { + if ( lobKind == LobKind.ALL_LOB ) { + return true; + } + final Long length = size.getLength(); + if ( length != null && length > 0 ) { + for ( TypeEntry typeEntry : typeEntries ) { + if ( length <= typeEntry.capacity ) { + return false; + } + } + } + return lobKind == LobKind.BIGGEST_LOB; + } + public static Builder builder(int sqlTypeCode, String typeNamePattern, Dialect dialect) { - return builder( sqlTypeCode, typeNamePattern, typeNamePattern, dialect ); + return builder( + sqlTypeCode, + JdbcType.isLob( sqlTypeCode ) ? LobKind.ALL_LOB : LobKind.NONE, + typeNamePattern, + typeNamePattern, + dialect + ); + } + + public static Builder builder(int sqlTypeCode, LobKind lobKind, String typeNamePattern, Dialect dialect) { + return builder( sqlTypeCode, lobKind, typeNamePattern, typeNamePattern, dialect ); + } + + public static Builder builder( + int sqlTypeCode, + String typeNamePattern, + String castTypeName, + Dialect dialect) { + return builder( + sqlTypeCode, + JdbcType.isLob( sqlTypeCode ) ? LobKind.ALL_LOB : LobKind.NONE, + typeNamePattern, + castTypeName, + dialect + ); + } + + public static Builder builder( + int sqlTypeCode, + LobKind lobKind, + String typeNamePattern, + String castTypeName, + Dialect dialect) { + return builder( sqlTypeCode, lobKind, typeNamePattern, null, castTypeName, dialect ); } public static Builder builder( int sqlTypeCode, String typeNamePattern, String castTypeNamePattern, + String castTypeName, Dialect dialect) { - return new Builder( sqlTypeCode, typeNamePattern, castTypeNamePattern, dialect ); + return builder( + sqlTypeCode, + JdbcType.isLob( sqlTypeCode ) ? LobKind.ALL_LOB : LobKind.NONE, + typeNamePattern, + castTypeNamePattern, + castTypeName, + dialect + ); + } + + public static Builder builder( + int sqlTypeCode, + LobKind lobKind, + String typeNamePattern, + String castTypeNamePattern, + String castTypeName, + Dialect dialect) { + return new Builder( sqlTypeCode, lobKind, typeNamePattern, castTypeNamePattern, castTypeName, dialect ); } public static class Builder { private final int sqlTypeCode; + private final LobKind lobKind; private final String typeNamePattern; private final String castTypeNamePattern; + private final String castTypeName; private final Dialect dialect; private final List typeEntries; private Builder( int sqlTypeCode, + LobKind lobKind, String typeNamePattern, String castTypeNamePattern, + String castTypeName, Dialect dialect) { this.sqlTypeCode = sqlTypeCode; + this.lobKind = lobKind; this.typeNamePattern = typeNamePattern; this.castTypeNamePattern = castTypeNamePattern; + this.castTypeName = castTypeName; this.dialect = dialect; this.typeEntries = new ArrayList<>(); } @@ -126,4 +204,10 @@ public class CapacityDependentDdlType extends DdlTypeImpl { return Long.compare( capacity, o.capacity ); } } + + public enum LobKind { + BIGGEST_LOB, + ALL_LOB, + NONE + } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/DdlTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/DdlTypeImpl.java index 9846e22a25..7cec3270e7 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/DdlTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/DdlTypeImpl.java @@ -10,6 +10,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.Size; import org.hibernate.internal.util.StringHelper; import org.hibernate.type.SqlTypes; +import org.hibernate.type.descriptor.java.CharacterJavaType; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.sql.DdlType; @@ -22,26 +23,59 @@ import org.hibernate.type.descriptor.sql.DdlType; public class DdlTypeImpl implements DdlType { private final int sqlTypeCode; + private final boolean isLob; private final String typeNamePattern; private final String castTypeNamePattern; + private final String castTypeName; private final boolean castTypeNameIsStatic; private final Dialect dialect; public DdlTypeImpl(int sqlTypeCode, String typeNamePattern, Dialect dialect) { - this( sqlTypeCode, typeNamePattern, typeNamePattern, dialect ); + this( sqlTypeCode, typeNamePattern, typeNamePattern, typeNamePattern, dialect ); } public DdlTypeImpl( int sqlTypeCode, String typeNamePattern, - String castTypeNamePattern, + String castTypeName, + Dialect dialect) { + this( sqlTypeCode, typeNamePattern, null, castTypeName, dialect ); + } + + public DdlTypeImpl( + int sqlTypeCode, + boolean isLob, + String typeNamePattern, + String castTypeName, + Dialect dialect) { + this( sqlTypeCode, isLob, typeNamePattern, null, castTypeName, dialect ); + } + + public DdlTypeImpl( + int sqlTypeCode, + String typeNamePattern, + String castTypeNamePattern, //optional, usually null + String castTypeName, + Dialect dialect) { + this( sqlTypeCode, JdbcType.isLob( sqlTypeCode ), typeNamePattern, castTypeNamePattern, castTypeName, dialect ); + } + + public DdlTypeImpl( + int sqlTypeCode, + boolean isLob, + String typeNamePattern, + String castTypeNamePattern, //optional, usually null + String castTypeName, Dialect dialect) { this.sqlTypeCode = sqlTypeCode; + this.isLob = isLob; this.typeNamePattern = typeNamePattern; this.castTypeNamePattern = castTypeNamePattern; - this.castTypeNameIsStatic = !castTypeNamePattern.contains( "$s" ) - && !castTypeNamePattern.contains( "$l" ) - && !castTypeNamePattern.contains( "$p" ); + this.castTypeName = castTypeName; + this.castTypeNameIsStatic = + !castTypeName.contains( "$s" ) + && !castTypeName.contains( "$p" ) + && !castTypeName.contains( "$l" ); this.dialect = dialect; } @@ -58,7 +92,7 @@ public class DdlTypeImpl implements DdlType { final int parenEnd = typeNamePattern.lastIndexOf( ')' ); return parenEnd + 1 == typeNamePattern.length() ? typeNamePattern.substring( 0, paren ) - : ( typeNamePattern.substring( 0, paren ) + typeNamePattern.substring( parenEnd + 1 ) ); + : typeNamePattern.substring( 0, paren ) + typeNamePattern.substring( parenEnd + 1 ); } return typeNamePattern; } @@ -68,6 +102,11 @@ public class DdlTypeImpl implements DdlType { return typeNamePattern; } + @Override + public boolean isLob(Size size) { + return isLob; + } + @Override public String getTypeName(Long size, Integer precision, Integer scale) { return replace( typeNamePattern, size, precision, scale ); @@ -84,38 +123,40 @@ public class DdlTypeImpl implements DdlType { //needed for cast(x as BigInteger(p)) scale = javaType.getDefaultSqlScale( dialect, jdbcType ); } + return castTypeNamePattern == null + ? getTypeName( length, precision, scale ) + : replace( castTypeNamePattern, length, precision, scale ); } - - return getTypeName( length, precision, scale ); } @Override public String getCastTypeName(JdbcType jdbcType, JavaType javaType) { - if ( castTypeNameIsStatic ) { - return castTypeNamePattern; + if ( javaType instanceof CharacterJavaType && jdbcType.isString() ) { + // nasty special case for casting to Character + return getCastTypeName( jdbcType, javaType, 1L, null, null ); } - Long length = null; - Integer precision = null; - Integer scale = null; + else if ( castTypeNameIsStatic ) { + return castTypeName; + } + else { + final Size size = dialect.getSizeStrategy() + .resolveSize( jdbcType, javaType, null, null, defaultLength( jdbcType ) ); + return replace( castTypeName, size.getLength(), size.getPrecision(), size.getScale() ); + } + } + + //TODO: move this to JdbcType?? + private Long defaultLength(JdbcType jdbcType) { switch ( jdbcType.getDdlTypeCode() ) { case SqlTypes.VARCHAR: - length = (long) dialect.getMaxVarcharLength(); - break; + return (long) dialect.getMaxVarcharLength(); case SqlTypes.NVARCHAR: - length = (long) dialect.getMaxNVarcharLength(); - break; + return (long) dialect.getMaxNVarcharLength(); case SqlTypes.VARBINARY: - length = (long) dialect.getMaxVarbinaryLength(); - break; + return (long) dialect.getMaxVarbinaryLength(); + default: + return null; } - final Size size = dialect.getSizeStrategy().resolveSize( - jdbcType, - javaType, - precision, - scale, - length - ); - return replace( castTypeNamePattern, size.getLength(), size.getPrecision(), size.getScale() ); } /** diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/rowid/RowIdType.java b/hibernate-core/src/test/java/org/hibernate/orm/test/rowid/RowIdType.java index a44b7cd2b4..1c3748520c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/rowid/RowIdType.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/rowid/RowIdType.java @@ -25,7 +25,7 @@ public class RowIdType implements UserType{ @Override public int getSqlType() { - return Types.JAVA_OBJECT; + return Types.ROWID; } public Class returnedClass() {