Skip to content

Commit b84032d

Browse files
committed
[hibernate#1915] Fix NPE when batching inserts
The NullPointerException because the method that converts the generated id from the database to a ResultSet was not implemented. We forgot about it because there was no test for identity generation with batching.
1 parent 637f234 commit b84032d

File tree

2 files changed

+68
-8
lines changed

2 files changed

+68
-8
lines changed

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

+65-3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import io.vertx.sqlclient.PropertyKind;
4545
import io.vertx.sqlclient.Row;
4646
import io.vertx.sqlclient.RowSet;
47+
import io.vertx.sqlclient.Tuple;
4748
import io.vertx.sqlclient.desc.ColumnDescriptor;
4849
import io.vertx.sqlclient.impl.RowBase;
4950

@@ -56,13 +57,71 @@
5657
*/
5758
public class ResultSetAdaptor implements ResultSet {
5859

59-
private final Iterator<Row> iterator;
60+
private final Iterator<? extends Row> iterator;
6061

6162
private final List<ColumnDescriptor> columnDescriptors;
6263
private final List<String> columnNames;
6364
private Row row;
6465
private boolean wasNull;
6566

67+
public ResultSetAdaptor(Object id, Class<?> idClass, String columnName) {
68+
requireNonNull( id );
69+
this.iterator = List.of( new RowAdaptor( id, idClass, columnName ) ).iterator();
70+
this.columnNames = columnName == null ? emptyList() : List.of( columnName );
71+
this.columnDescriptors = List.of( toColumnDescriptor( idClass, columnName ) );
72+
}
73+
74+
private static class RowAdaptor implements Row {
75+
private final Object id;
76+
private final Class<?> idClass;
77+
private final String columnName;
78+
79+
public RowAdaptor(Object id, Class<?> idClass, String columnName) {
80+
this.id = id;
81+
this.idClass = idClass;
82+
this.columnName = columnName;
83+
}
84+
85+
@Override
86+
public Object getValue(String column) {
87+
return id;
88+
}
89+
90+
@Override
91+
public String getColumnName(int pos) {
92+
return columnName;
93+
}
94+
95+
@Override
96+
public int getColumnIndex(String column) {
97+
return 0;
98+
}
99+
100+
@Override
101+
public Object getValue(int pos) {
102+
return id;
103+
}
104+
105+
@Override
106+
public Tuple addValue(Object value) {
107+
return null;
108+
}
109+
110+
@Override
111+
public int size() {
112+
return 1;
113+
}
114+
115+
@Override
116+
public void clear() {
117+
}
118+
119+
@Override
120+
public List<Class<?>> types() {
121+
return List.of( idClass );
122+
}
123+
}
124+
66125
public ResultSetAdaptor(RowSet<Row> rows) {
67126
requireNonNull( rows );
68127
this.iterator = rows.iterator();
@@ -83,7 +142,11 @@ private ResultSetAdaptor(RowSet<Row> rows, Row row, String idColumnName, Class<?
83142
requireNonNull( idColumnName );
84143
this.iterator = List.of( row ).iterator();
85144
this.columnNames = List.of( idColumnName );
86-
ColumnDescriptor columnDescriptor = new ColumnDescriptor() {
145+
this.columnDescriptors = List.of( toColumnDescriptor( idClass, idColumnName ) );
146+
}
147+
148+
private static ColumnDescriptor toColumnDescriptor(Class<?> idClass, String idColumnName) {
149+
return new ColumnDescriptor() {
87150
@Override
88151
public String name() {
89152
return idColumnName;
@@ -104,7 +167,6 @@ public JDBCType jdbcType() {
104167
return null;
105168
}
106169
};
107-
this.columnDescriptors = List.of( columnDescriptor );
108170
}
109171

110172
private static class RowFromId extends RowBase {

hibernate-reactive-core/src/main/java/org/hibernate/reactive/pool/BatchingConnection.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import java.util.concurrent.CompletionStage;
1313

1414

15+
import org.hibernate.reactive.adaptor.impl.ResultSetAdaptor;
16+
1517
import io.vertx.sqlclient.spi.DatabaseMetadata;
1618

1719
import static org.hibernate.reactive.util.impl.CompletionStages.voidFuture;
@@ -169,11 +171,7 @@ public CompletionStage<ResultSet> insertAndSelectIdentifierAsResultSet(
169171
Class<?> idClass,
170172
String idColumnName) {
171173
return insertAndSelectIdentifier( sql, paramValues, idClass, idColumnName )
172-
.thenApply( this::convertToResultSet );
173-
}
174-
175-
private ResultSet convertToResultSet(Object o) {
176-
return null;
174+
.thenApply( id -> new ResultSetAdaptor( id, idClass, idColumnName ) );
177175
}
178176

179177
public CompletionStage<ReactiveConnection.Result> select(String sql) {

0 commit comments

Comments
 (0)