diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java index b1490380b477..21ecacf240ca 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java @@ -1095,6 +1095,8 @@ public LockingSupport getLockingSupport() { @Override public boolean useInputStreamToInsertBlob() { + // PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs, + // so disable stream bindings for this dialect completely return false; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java index 692a6e870ebc..9ff508aa8854 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java @@ -1103,7 +1103,16 @@ public boolean supportsLobValueChangePropagation() { } @Override - public boolean useInputStreamToInsertBlob() { + public boolean useConnectionToCreateLob() { + return false; + } + + @Override + public boolean supportsNationalizedMethods() { + // See HHH-12753, HHH-18314, HHH-19201 + // Old DB2 JDBC drivers do not support setNClob, setNCharcterStream or setNString. + // In more recent driver versions, some methods just delegate to the non-N variant, but others still fail. + // Ultimately, let's just avoid the N variant methods on DB2 altogether return false; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java index d54a97077b66..ef978f66baf7 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java @@ -29,6 +29,7 @@ import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.DmlTargetColumnQualifierSupport; +import org.hibernate.dialect.OracleServerConfiguration; import org.hibernate.dialect.temptable.OracleLocalTemporaryTableStrategy; import org.hibernate.dialect.temptable.StandardGlobalTemporaryTableStrategy; import org.hibernate.dialect.temptable.TemporaryTableStrategy; @@ -206,6 +207,18 @@ protected void applyAggregateColumnCheck(StringBuilder buf, AggregateColumn aggr } }; + // Is it an Autonomous Database Cloud Service? + protected final boolean autonomous; + + // Is MAX_STRING_SIZE set to EXTENDED? + protected final boolean extended; + + // Is the database accessed using a database service protected by Application Continuity. + protected final boolean applicationContinuity; + + protected final int driverMajorVersion; + protected final int driverMinorVersion; + private final LockingSupport lockingSupport; public OracleLegacyDialect() { @@ -213,13 +226,39 @@ public OracleLegacyDialect() { } public OracleLegacyDialect(DatabaseVersion version) { - super(version); + super( version ); lockingSupport = new OracleLockingSupport( version ); + autonomous = false; + extended = false; + applicationContinuity = false; + driverMajorVersion = 19; + driverMinorVersion = 0; } public OracleLegacyDialect(DialectResolutionInfo info) { - super(info); + this( info, OracleServerConfiguration.fromDialectResolutionInfo( info ) ); + } + + public OracleLegacyDialect(DialectResolutionInfo info, OracleServerConfiguration serverConfiguration) { + super( info ); lockingSupport = new OracleLockingSupport( getVersion() ); + autonomous = serverConfiguration.isAutonomous(); + extended = serverConfiguration.isExtended(); + applicationContinuity = serverConfiguration.isApplicationContinuity(); + this.driverMinorVersion = serverConfiguration.getDriverMinorVersion(); + this.driverMajorVersion = serverConfiguration.getDriverMajorVersion(); + } + + public boolean isAutonomous() { + return autonomous; + } + + public boolean isExtended() { + return extended; + } + + public boolean isApplicationContinuity() { + return applicationContinuity; } @Override @@ -1662,11 +1701,11 @@ public boolean supportsFromClauseInUpdate() { @Override public boolean useInputStreamToInsertBlob() { - // see HHH-18206 - return false; + // If application continuity is enabled, don't use stream bindings, since a replay could otherwise fail + // if the underlying stream doesn't support mark and reset + return !isApplicationContinuity(); } - @Override public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) { if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java index 7b4e27b9bdff..a00b1cc49d35 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java @@ -946,6 +946,8 @@ public GenerationType getNativeValueGenerationStrategy() { @Override public boolean useInputStreamToInsertBlob() { + // PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs, + // so disable stream bindings for this dialect completely return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java index b7b24cbe7fae..df208a965798 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java @@ -993,6 +993,8 @@ public String getForUpdateSkipLockedString(String aliases) { @Override public boolean useInputStreamToInsertBlob() { + // PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs, + // so disable stream bindings for this dialect completely return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java index 0431fd0a604d..bd7e5d95381e 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java @@ -939,7 +939,16 @@ public boolean supportsLobValueChangePropagation() { } @Override - public boolean useInputStreamToInsertBlob() { + public boolean useConnectionToCreateLob() { + return false; + } + + @Override + public boolean supportsNationalizedMethods() { + // See HHH-12753, HHH-18314, HHH-19201 + // Old DB2 JDBC drivers do not support setNClob, setNCharcterStream or setNString. + // In more recent driver versions, some methods just delegate to the non-N variant, but others still fail. + // Ultimately, let's just avoid the N variant methods on DB2 altogether return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java index 6d2692376fcb..8348512e1349 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java @@ -1811,11 +1811,11 @@ public String[] getDropEnumTypeCommand(String name) { @Override public boolean useInputStreamToInsertBlob() { - // see HHH-18206 - return false; + // If application continuity is enabled, don't use stream bindings, since a replay could otherwise fail + // if the underlying stream doesn't support mark and reset + return !isApplicationContinuity(); } - @Override public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) { return isNotEmpty( checkConstraint.getOptions() ) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java index 9449aa152372..e2185157b3a5 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java @@ -904,6 +904,8 @@ public GenerationType getNativeValueGenerationStrategy() { @Override public boolean useInputStreamToInsertBlob() { + // PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs, + // so disable stream bindings for this dialect completely return false; } diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/blob/BasicBlobTest.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/blob/BasicBlobTest.java index 74d7ead88bd2..02baf048950e 100644 --- a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/blob/BasicBlobTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/blob/BasicBlobTest.java @@ -89,6 +89,7 @@ public void testGenerateProxyStream() throws URISyntaxException { .getResource( "org/hibernate/orm/test/envers/integration/blob/blob.txt" ).toURI() ); try (final InputStream stream = new BufferedInputStream( Files.newInputStream( path ) )) { + final long length = Files.size( path ); doInJPA( this::entityManagerFactory, entityManager -> { final Asset asset = new Asset(); asset.setFileName( "blob.txt" ); @@ -108,7 +109,7 @@ public void testGenerateProxyStream() throws URISyntaxException { // H2, MySQL, Oracle, SQL Server work this way. // // - Blob blob = BlobProxy.generateProxy( stream, 9192L ); + Blob blob = BlobProxy.generateProxy( stream, length ); asset.setData( blob ); entityManager.persist( asset );