Skip to content

Commit 746e342

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 9a5d6bb commit 746e342

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
@@ -1095,6 +1095,8 @@ public LockingSupport getLockingSupport() {
10951095

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

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
@@ -1103,7 +1103,16 @@ public boolean supportsLobValueChangePropagation() {
11031103
}
11041104

11051105
@Override
1106-
public boolean useInputStreamToInsertBlob() {
1106+
public boolean useConnectionToCreateLob() {
1107+
return false;
1108+
}
1109+
1110+
@Override
1111+
public boolean supportsNationalizedMethods() {
1112+
// See HHH-12753, HHH-18314, HHH-19201
1113+
// Old DB2 JDBC drivers do not support setNClob, setNCharcterStream or setNString.
1114+
// In more recent driver versions, some methods just delegate to the non-N variant, but others still fail.
1115+
// Ultimately, let's just avoid the N variant methods on DB2 altogether
11071116
return false;
11081117
}
11091118

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
@@ -1662,11 +1701,11 @@ public boolean supportsFromClauseInUpdate() {
16621701

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

1669-
16701709
@Override
16711710
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
16721711
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
@@ -946,6 +946,8 @@ public GenerationType getNativeValueGenerationStrategy() {
946946

947947
@Override
948948
public boolean useInputStreamToInsertBlob() {
949+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
950+
// so disable stream bindings for this dialect completely
949951
return false;
950952
}
951953

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

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

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

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

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

941941
@Override
942-
public boolean useInputStreamToInsertBlob() {
942+
public boolean useConnectionToCreateLob() {
943+
return false;
944+
}
945+
946+
@Override
947+
public boolean supportsNationalizedMethods() {
948+
// See HHH-12753, HHH-18314, HHH-19201
949+
// Old DB2 JDBC drivers do not support setNClob, setNCharcterStream or setNString.
950+
// In more recent driver versions, some methods just delegate to the non-N variant, but others still fail.
951+
// Ultimately, let's just avoid the N variant methods on DB2 altogether
943952
return false;
944953
}
945954

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

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

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

1818-
18191819
@Override
18201820
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
18211821
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
@@ -904,6 +904,8 @@ public GenerationType getNativeValueGenerationStrategy() {
904904

905905
@Override
906906
public boolean useInputStreamToInsertBlob() {
907+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
908+
// so disable stream bindings for this dialect completely
907909
return false;
908910
}
909911

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)