Skip to content

Commit 9455a42

Browse files
committed
HHH-19201 Avoid materializing byte[]/String for Blob/Clob when possible.
* Only disable stream binding when Oracle application continuity is enabled * Enable stream binding on DB2 unconditionally and just disable nationalized methods
1 parent c496a1b commit 9455a42

File tree

9 files changed

+77
-11
lines changed

9 files changed

+77
-11
lines changed

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,8 @@ public LockingSupport getLockingSupport() {
10941094

10951095
@Override
10961096
public boolean useInputStreamToInsertBlob() {
1097+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
1098+
// so disable stream bindings for this dialect completely
10971099
return false;
10981100
}
10991101

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,16 @@ public boolean supportsLobValueChangePropagation() {
10951095
}
10961096

10971097
@Override
1098-
public boolean useInputStreamToInsertBlob() {
1098+
public boolean useConnectionToCreateLob() {
1099+
return false;
1100+
}
1101+
1102+
@Override
1103+
public boolean supportsNationalizedMethods() {
1104+
// See HHH-12753, HHH-18314, HHH-19201
1105+
// Old DB2 JDBC drivers do not support setNClob, setNCharcterStream or setNString.
1106+
// In more recent driver versions, some methods just delegate to the non-N variant, but others still fail.
1107+
// Ultimately, let's just avoid the N variant methods on DB2 altogether
10991108
return false;
11001109
}
11011110

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.hibernate.dialect.DatabaseVersion;
3030
import org.hibernate.dialect.Dialect;
3131
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
32+
import org.hibernate.dialect.OracleServerConfiguration;
3233
import org.hibernate.dialect.temptable.OracleLocalTemporaryTableStrategy;
3334
import org.hibernate.dialect.temptable.StandardGlobalTemporaryTableStrategy;
3435
import org.hibernate.dialect.temptable.TemporaryTableStrategy;
@@ -206,20 +207,58 @@ protected void applyAggregateColumnCheck(StringBuilder buf, AggregateColumn aggr
206207
}
207208
};
208209

210+
// Is it an Autonomous Database Cloud Service?
211+
protected final boolean autonomous;
212+
213+
// Is MAX_STRING_SIZE set to EXTENDED?
214+
protected final boolean extended;
215+
216+
// Is the database accessed using a database service protected by Application Continuity.
217+
protected final boolean applicationContinuity;
218+
219+
protected final int driverMajorVersion;
220+
protected final int driverMinorVersion;
221+
209222
private final LockingSupport lockingSupport;
210223

211224
public OracleLegacyDialect() {
212225
this( DatabaseVersion.make( 8, 0 ) );
213226
}
214227

215228
public OracleLegacyDialect(DatabaseVersion version) {
216-
super(version);
229+
super( version );
217230
lockingSupport = new OracleLockingSupport( version );
231+
autonomous = false;
232+
extended = false;
233+
applicationContinuity = false;
234+
driverMajorVersion = 19;
235+
driverMinorVersion = 0;
218236
}
219237

220238
public OracleLegacyDialect(DialectResolutionInfo info) {
221-
super(info);
239+
this( info, OracleServerConfiguration.fromDialectResolutionInfo( info ) );
240+
}
241+
242+
public OracleLegacyDialect(DialectResolutionInfo info, OracleServerConfiguration serverConfiguration) {
243+
super( info );
222244
lockingSupport = new OracleLockingSupport( getVersion() );
245+
autonomous = serverConfiguration.isAutonomous();
246+
extended = serverConfiguration.isExtended();
247+
applicationContinuity = serverConfiguration.isApplicationContinuity();
248+
this.driverMinorVersion = serverConfiguration.getDriverMinorVersion();
249+
this.driverMajorVersion = serverConfiguration.getDriverMajorVersion();
250+
}
251+
252+
public boolean isAutonomous() {
253+
return autonomous;
254+
}
255+
256+
public boolean isExtended() {
257+
return extended;
258+
}
259+
260+
public boolean isApplicationContinuity() {
261+
return applicationContinuity;
223262
}
224263

225264
@Override
@@ -1661,11 +1700,11 @@ public boolean supportsFromClauseInUpdate() {
16611700

16621701
@Override
16631702
public boolean useInputStreamToInsertBlob() {
1664-
// see HHH-18206
1665-
return false;
1703+
// If application continuity is enabled, don't use stream bindings, since a replay could otherwise fail
1704+
// if the underlying stream doesn't support mark and reset
1705+
return !isApplicationContinuity();
16661706
}
16671707

1668-
16691708
@Override
16701709
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
16711710
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,8 @@ public GenerationType getNativeValueGenerationStrategy() {
944944

945945
@Override
946946
public boolean useInputStreamToInsertBlob() {
947+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
948+
// so disable stream bindings for this dialect completely
947949
return false;
948950
}
949951

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,8 @@ public String getForUpdateSkipLockedString(String aliases) {
992992

993993
@Override
994994
public boolean useInputStreamToInsertBlob() {
995+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
996+
// so disable stream bindings for this dialect completely
995997
return false;
996998
}
997999

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,16 @@ public boolean supportsLobValueChangePropagation() {
895895
}
896896

897897
@Override
898-
public boolean useInputStreamToInsertBlob() {
898+
public boolean useConnectionToCreateLob() {
899+
return false;
900+
}
901+
902+
@Override
903+
public boolean supportsNationalizedMethods() {
904+
// See HHH-12753, HHH-18314, HHH-19201
905+
// Old DB2 JDBC drivers do not support setNClob, setNCharcterStream or setNString.
906+
// In more recent driver versions, some methods just delegate to the non-N variant, but others still fail.
907+
// Ultimately, let's just avoid the N variant methods on DB2 altogether
899908
return false;
900909
}
901910

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,11 +1810,11 @@ public String[] getDropEnumTypeCommand(String name) {
18101810

18111811
@Override
18121812
public boolean useInputStreamToInsertBlob() {
1813-
// see HHH-18206
1814-
return false;
1813+
// If application continuity is enabled, don't use stream bindings, since a replay could otherwise fail
1814+
// if the underlying stream doesn't support mark and reset
1815+
return !isApplicationContinuity();
18151816
}
18161817

1817-
18181818
@Override
18191819
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
18201820
return isNotEmpty( checkConstraint.getOptions() )

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,8 @@ public GenerationType getNativeValueGenerationStrategy() {
902902

903903
@Override
904904
public boolean useInputStreamToInsertBlob() {
905+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
906+
// so disable stream bindings for this dialect completely
905907
return false;
906908
}
907909

hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/blob/BasicBlobTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public void testGenerateProxyStream() throws URISyntaxException {
8989
.getResource( "org/hibernate/orm/test/envers/integration/blob/blob.txt" ).toURI() );
9090

9191
try (final InputStream stream = new BufferedInputStream( Files.newInputStream( path ) )) {
92+
final long length = Files.size( path );
9293
doInJPA( this::entityManagerFactory, entityManager -> {
9394
final Asset asset = new Asset();
9495
asset.setFileName( "blob.txt" );
@@ -108,7 +109,7 @@ public void testGenerateProxyStream() throws URISyntaxException {
108109
// H2, MySQL, Oracle, SQL Server work this way.
109110
//
110111
//
111-
Blob blob = BlobProxy.generateProxy( stream, 9192L );
112+
Blob blob = BlobProxy.generateProxy( stream, length );
112113

113114
asset.setData( blob );
114115
entityManager.persist( asset );

0 commit comments

Comments
 (0)