Skip to content

Commit 7767270

Browse files
gavinkingDavideD
authored andcommitted
use NullValue to bind null values
fixes #843
1 parent 9f37f21 commit 7767270

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

hibernate-reactive-core/src/main/java/org/hibernate/reactive/adaptor/impl/PreparedStatementAdaptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.sql.Clob;
2222
import java.sql.Connection;
2323
import java.sql.Date;
24+
import java.sql.JDBCType;
2425
import java.sql.NClob;
2526
import java.sql.ParameterMetaData;
2627
import java.sql.PreparedStatement;
@@ -93,7 +94,7 @@ public int executeUpdate() {
9394

9495
@Override
9596
public void setNull(int parameterIndex, int sqlType) {
96-
put( parameterIndex, null );
97+
put( parameterIndex, JDBCType.valueOf(sqlType) );
9798
}
9899

99100
@Override

hibernate-reactive-core/src/main/java/org/hibernate/reactive/pool/impl/SqlClientConnection.java

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
*/
66
package org.hibernate.reactive.pool.impl;
77

8+
import java.sql.JDBCType;
89
import java.sql.ResultSet;
10+
import java.sql.Types;
911
import java.util.ArrayList;
1012
import java.util.List;
1113
import java.util.Objects;
1214
import java.util.concurrent.CompletionStage;
1315

16+
import io.vertx.sqlclient.data.NullValue;
1417
import org.hibernate.engine.jdbc.internal.FormatStyle;
1518
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
1619
import org.hibernate.reactive.adaptor.impl.ResultSetAdaptor;
@@ -51,13 +54,15 @@ public class SqlClientConnection implements ReactiveConnection {
5154

5255
@Override
5356
public CompletionStage<Integer> update(String sql, Object[] paramValues) {
57+
translateNulls( paramValues );
5458
return update( sql, Tuple.wrap( paramValues ) );
5559
}
5660

5761
@Override
5862
public CompletionStage<int[]> update(String sql, List<Object[]> batchParamValues) {
5963
final List<Tuple> tuples = new ArrayList<>( batchParamValues.size() );
60-
for ( Object[] paramValues : batchParamValues) {
64+
for ( Object[] paramValues : batchParamValues ) {
65+
translateNulls( paramValues );
6166
tuples.add( Tuple.wrap( paramValues ) );
6267
}
6368
return updateBatch( sql, tuples );
@@ -72,11 +77,13 @@ public CompletionStage<Void> update(String sql, Object[] paramValues,
7277

7378
@Override
7479
public CompletionStage<Long> insertAndSelectIdentifier(String sql, Object[] paramValues) {
80+
translateNulls( paramValues );
7581
return insertAndSelectIdentifier( sql, Tuple.wrap( paramValues ) );
7682
}
7783

7884
@Override
7985
public CompletionStage<Long> selectIdentifier(String sql, Object[] paramValues) {
86+
translateNulls( paramValues );
8087
return preparedQuery( sql, Tuple.wrap( paramValues ) )
8188
.thenApply( rowSet -> {
8289
for (Row row: rowSet) {
@@ -93,11 +100,13 @@ public CompletionStage<Result> select(String sql) {
93100

94101
@Override
95102
public CompletionStage<Result> select(String sql, Object[] paramValues) {
103+
translateNulls( paramValues );
96104
return preparedQuery( sql, Tuple.wrap( paramValues ) ).thenApply(RowSetResult::new);
97105
}
98106

99107
@Override
100108
public CompletionStage<ResultSet> selectJdbc(String sql, Object[] paramValues) {
109+
translateNulls( paramValues );
101110
return preparedQuery( sql, Tuple.wrap( paramValues ) ).thenApply(ResultSetAdaptor::new);
102111
}
103112

@@ -264,4 +273,58 @@ public Object[] next() {
264273
public CompletionStage<Void> executeBatch() {
265274
return voidFuture();
266275
}
276+
277+
private static void translateNulls(Object[] paramValues) {
278+
for (int i = 0; i < paramValues.length; i++) {
279+
Object arg = paramValues[i];
280+
if (arg instanceof JDBCType) {
281+
paramValues[i] = toNullValue( (JDBCType) arg );
282+
}
283+
}
284+
}
285+
286+
private static NullValue toNullValue(JDBCType jdbcType) {
287+
switch ( jdbcType.getVendorTypeNumber() ) {
288+
case Types.BOOLEAN:
289+
case Types.BIT: //we misuse BIT in H5
290+
return NullValue.Boolean;
291+
case Types.VARCHAR:
292+
case Types.NVARCHAR:
293+
case Types.CHAR:
294+
case Types.NCHAR:
295+
case Types.CLOB:
296+
case Types.NCLOB:
297+
case Types.LONGVARCHAR:
298+
case Types.LONGNVARCHAR:
299+
return NullValue.String;
300+
case Types.FLOAT:
301+
case Types.DOUBLE:
302+
case Types.REAL:
303+
return NullValue.Double;
304+
case Types.BIGINT:
305+
return NullValue.Long;
306+
case Types.INTEGER:
307+
return NullValue.Integer;
308+
case Types.SMALLINT:
309+
case Types.TINYINT: //should really map to Byte
310+
return NullValue.Short;
311+
case Types.DECIMAL:
312+
return NullValue.BigDecimal;
313+
case Types.BINARY:
314+
case Types.BLOB:
315+
case Types.LONGVARBINARY:
316+
return NullValue.Buffer;
317+
case Types.TIMESTAMP:
318+
return NullValue.LocalDateTime;
319+
case Types.DATE:
320+
return NullValue.LocalDate;
321+
case Types.TIME:
322+
return NullValue.LocalTime;
323+
case Types.TIMESTAMP_WITH_TIMEZONE:
324+
return NullValue.OffsetDateTime;
325+
case Types.TIME_WITH_TIMEZONE:
326+
return NullValue.OffsetTime;
327+
default: return null;
328+
}
329+
}
267330
}

0 commit comments

Comments
 (0)