Skip to content

Commit f5219a7

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 d3be472 commit f5219a7

File tree

9 files changed

+85
-9
lines changed

9 files changed

+85
-9
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
@@ -1043,6 +1043,8 @@ public boolean supportsOuterJoinForUpdate() {
10431043

10441044
@Override
10451045
public boolean useInputStreamToInsertBlob() {
1046+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
1047+
// so disable stream bindings for this dialect completely
10461048
return false;
10471049
}
10481050

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,20 @@ public boolean supportsLobValueChangePropagation() {
870870
return false;
871871
}
872872

873+
@Override
874+
public boolean useConnectionToCreateLob() {
875+
return false;
876+
}
877+
878+
@Override
879+
public boolean supportsNationalizedMethods() {
880+
// See HHH-12753, HHH-18314, HHH-19201
881+
// Old DB2 JDBC drivers do not support setNClob, setNCharcterStream or setNString.
882+
// In more recent driver versions, some methods just delegate to the non-N variant, but others still fail.
883+
// Ultimately, let's just avoid the N variant methods on DB2 altogether
884+
return false;
885+
}
886+
873887
@Override
874888
public boolean doesReadCommittedCauseWritersToBlockReaders() {
875889
return true;

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
@@ -28,6 +28,7 @@
2828
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
2929
import org.hibernate.dialect.DatabaseVersion;
3030
import org.hibernate.dialect.Dialect;
31+
import org.hibernate.dialect.OracleServerConfiguration;
3132
import org.hibernate.dialect.OracleBooleanJdbcType;
3233
import org.hibernate.dialect.OracleJdbcHelper;
3334
import org.hibernate.dialect.OracleJsonJdbcType;
@@ -188,16 +189,54 @@ public class OracleLegacyDialect extends Dialect {
188189
private final UniqueDelegate uniqueDelegate = new CreateTableUniqueDelegate(this);
189190
private final SequenceSupport oracleSequenceSupport = OracleSequenceSupport.getInstance(this);
190191

192+
// Is it an Autonomous Database Cloud Service?
193+
protected final boolean autonomous;
194+
195+
// Is MAX_STRING_SIZE set to EXTENDED?
196+
protected final boolean extended;
197+
198+
// Is the database accessed using a database service protected by Application Continuity.
199+
protected final boolean applicationContinuity;
200+
201+
protected final int driverMajorVersion;
202+
protected final int driverMinorVersion;
203+
191204
public OracleLegacyDialect() {
192205
this( DatabaseVersion.make( 8, 0 ) );
193206
}
194207

195208
public OracleLegacyDialect(DatabaseVersion version) {
196-
super(version);
209+
super( version );
210+
autonomous = false;
211+
extended = false;
212+
applicationContinuity = false;
213+
driverMajorVersion = 19;
214+
driverMinorVersion = 0;
197215
}
198216

199217
public OracleLegacyDialect(DialectResolutionInfo info) {
200-
super(info);
218+
this( info, OracleServerConfiguration.fromDialectResolutionInfo( info ) );
219+
}
220+
221+
public OracleLegacyDialect(DialectResolutionInfo info, OracleServerConfiguration serverConfiguration) {
222+
super( info );
223+
autonomous = serverConfiguration.isAutonomous();
224+
extended = serverConfiguration.isExtended();
225+
applicationContinuity = serverConfiguration.isApplicationContinuity();
226+
this.driverMinorVersion = serverConfiguration.getDriverMinorVersion();
227+
this.driverMajorVersion = serverConfiguration.getDriverMajorVersion();
228+
}
229+
230+
public boolean isAutonomous() {
231+
return autonomous;
232+
}
233+
234+
public boolean isExtended() {
235+
return extended;
236+
}
237+
238+
public boolean isApplicationContinuity() {
239+
return applicationContinuity;
201240
}
202241

203242
@Override
@@ -1587,10 +1626,10 @@ public boolean supportsFromClauseInUpdate() {
15871626

15881627
@Override
15891628
public boolean useInputStreamToInsertBlob() {
1590-
// see HHH-18206
1591-
return false;
1629+
// If application continuity is enabled, don't use stream bindings, since a replay could otherwise fail
1630+
// if the underlying stream doesn't support mark and reset
1631+
return !isApplicationContinuity();
15921632
}
1593-
15941633
@Override
15951634
public String getDual() {
15961635
return "dual";

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
@@ -861,6 +861,8 @@ public boolean supportsOuterJoinForUpdate() {
861861

862862
@Override
863863
public boolean useInputStreamToInsertBlob() {
864+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
865+
// so disable stream bindings for this dialect completely
864866
return false;
865867
}
866868

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,8 @@ public boolean supportsOuterJoinForUpdate() {
10121012

10131013
@Override
10141014
public boolean useInputStreamToInsertBlob() {
1015+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
1016+
// so disable stream bindings for this dialect completely
10151017
return false;
10161018
}
10171019

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,20 @@ public boolean supportsLobValueChangePropagation() {
965965
return false;
966966
}
967967

968+
@Override
969+
public boolean useConnectionToCreateLob() {
970+
return false;
971+
}
972+
973+
@Override
974+
public boolean supportsNationalizedMethods() {
975+
// See HHH-12753, HHH-18314, HHH-19201
976+
// Old DB2 JDBC drivers do not support setNClob, setNCharcterStream or setNString.
977+
// In more recent driver versions, some methods just delegate to the non-N variant, but others still fail.
978+
// Ultimately, let's just avoid the N variant methods on DB2 altogether
979+
return false;
980+
}
981+
968982
@Override
969983
public boolean doesReadCommittedCauseWritersToBlockReaders() {
970984
return true;

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

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

17111711
@Override
17121712
public boolean useInputStreamToInsertBlob() {
1713-
// see HHH-18206
1714-
return false;
1713+
// If application continuity is enabled, don't use stream bindings, since a replay could otherwise fail
1714+
// if the underlying stream doesn't support mark and reset
1715+
return !isApplicationContinuity();
17151716
}
1716-
17171717
@Override
17181718
public String getDual() {
17191719
return "dual";

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,8 @@ public boolean supportsOuterJoinForUpdate() {
927927

928928
@Override
929929
public boolean useInputStreamToInsertBlob() {
930+
// PG-JDBC treats setBinaryStream()/setCharacterStream() calls like bytea/varchar, which are not LOBs,
931+
// so disable stream bindings for this dialect completely
930932
return false;
931933
}
932934

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
@@ -90,6 +90,7 @@ public void testGenerateProxyStream() throws URISyntaxException {
9090
.getResource( "org/hibernate/orm/test/envers/integration/blob/blob.txt" ).toURI() );
9191

9292
try (final InputStream stream = new BufferedInputStream( Files.newInputStream( path ) )) {
93+
final long length = Files.size( path );
9394
doInJPA( this::entityManagerFactory, entityManager -> {
9495
final Asset asset = new Asset();
9596
asset.setFileName( "blob.txt" );
@@ -109,7 +110,7 @@ public void testGenerateProxyStream() throws URISyntaxException {
109110
// H2, MySQL, Oracle, SQL Server work this way.
110111
//
111112
//
112-
Blob blob = BlobProxy.generateProxy( stream, 1431 );
113+
Blob blob = BlobProxy.generateProxy( stream, length );
113114

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

0 commit comments

Comments
 (0)