4747import org .apache .commons .logging .Log ;
4848import org .apache .commons .logging .LogFactory ;
4949import org .reactivestreams .Publisher ;
50+
5051import org .springframework .dao .DataAccessException ;
5152import org .springframework .data .domain .Pageable ;
5253import org .springframework .data .domain .Sort ;
5354import org .springframework .data .r2dbc .UncategorizedR2dbcException ;
5455import org .springframework .data .r2dbc .function .connectionfactory .ConnectionProxy ;
5556import org .springframework .data .r2dbc .function .convert .ColumnMapRowMapper ;
57+ import org .springframework .data .r2dbc .function .convert .OutboundRow ;
5658import org .springframework .data .r2dbc .function .convert .SettableValue ;
5759import org .springframework .data .r2dbc .support .R2dbcExceptionTranslator ;
5860import org .springframework .jdbc .core .SqlProvider ;
@@ -365,26 +367,30 @@ <T> FetchSpec<T> exchange(String sql, BiFunction<Row, RowMetadata, T> mappingFun
365367
366368 public ExecuteSpecSupport bind (int index , Object value ) {
367369
370+ Assert .notNull (value , () -> String .format ("Value at index %d must not be null. Use bindNull(…) instead." , index ));
371+
368372 Map <Integer , SettableValue > byIndex = new LinkedHashMap <>(this .byIndex );
369- byIndex .put (index , new SettableValue (index , value , null ));
373+ byIndex .put (index , new SettableValue (value , value . getClass () ));
370374
371375 return createInstance (byIndex , this .byName , this .sqlSupplier );
372376 }
373377
374378 public ExecuteSpecSupport bindNull (int index , Class <?> type ) {
375379
376380 Map <Integer , SettableValue > byIndex = new LinkedHashMap <>(this .byIndex );
377- byIndex .put (index , new SettableValue (index , null , type ));
381+ byIndex .put (index , new SettableValue (null , type ));
378382
379383 return createInstance (byIndex , this .byName , this .sqlSupplier );
380384 }
381385
382386 public ExecuteSpecSupport bind (String name , Object value ) {
383387
384388 Assert .hasText (name , "Parameter name must not be null or empty!" );
389+ Assert .notNull (value ,
390+ () -> String .format ("Value for parameter %s must not be null. Use bindNull(…) instead." , name ));
385391
386392 Map <String , SettableValue > byName = new LinkedHashMap <>(this .byName );
387- byName .put (name , new SettableValue (name , value , null ));
393+ byName .put (name , new SettableValue (value , value . getClass () ));
388394
389395 return createInstance (this .byIndex , byName , this .sqlSupplier );
390396 }
@@ -394,7 +400,7 @@ public ExecuteSpecSupport bindNull(String name, Class<?> type) {
394400 Assert .hasText (name , "Parameter name must not be null or empty!" );
395401
396402 Map <String , SettableValue > byName = new LinkedHashMap <>(this .byName );
397- byName .put (name , new SettableValue (name , null , type ));
403+ byName .put (name , new SettableValue (null , type ));
398404
399405 return createInstance (this .byIndex , byName , this .sqlSupplier );
400406 }
@@ -832,9 +838,11 @@ class DefaultGenericInsertSpec<T> implements GenericInsertSpec<T> {
832838 public GenericInsertSpec value (String field , Object value ) {
833839
834840 Assert .notNull (field , "Field must not be null!" );
841+ Assert .notNull (value ,
842+ () -> String .format ("Value for field %s must not be null. Use nullValue(…) instead." , field ));
835843
836844 Map <String , SettableValue > byName = new LinkedHashMap <>(this .byName );
837- byName .put (field , new SettableValue (field , value , null ));
845+ byName .put (field , new SettableValue (value , value . getClass () ));
838846
839847 return new DefaultGenericInsertSpec <>(this .table , byName , this .mappingFunction );
840848 }
@@ -845,7 +853,7 @@ public GenericInsertSpec nullValue(String field, Class<?> type) {
845853 Assert .notNull (field , "Field must not be null!" );
846854
847855 Map <String , SettableValue > byName = new LinkedHashMap <>(this .byName );
848- byName .put (field , new SettableValue (field , null , type ));
856+ byName .put (field , new SettableValue (null , type ));
849857
850858 return new DefaultGenericInsertSpec <>(this .table , byName , this .mappingFunction );
851859 }
@@ -885,7 +893,7 @@ private <R> FetchSpec<R> exchange(BiFunction<Row, RowMetadata, R> mappingFunctio
885893
886894 Statement statement = it .createStatement (sql ).returnGeneratedValues ();
887895
888- byName .forEach ((k , v ) -> bindableInsert .bind (statement , v ));
896+ byName .forEach ((k , v ) -> bindableInsert .bind (statement , k , v ));
889897
890898 return statement ;
891899 };
@@ -989,12 +997,16 @@ public Mono<Integer> rowsUpdated() {
989997
990998 private <MR > FetchSpec <MR > exchange (Object toInsert , BiFunction <Row , RowMetadata , MR > mappingFunction ) {
991999
992- List <SettableValue > insertValues = dataAccessStrategy .getValuesToInsert (toInsert );
1000+ OutboundRow outboundRow = dataAccessStrategy .getOutboundRow (toInsert );
1001+
9931002 Set <String > columns = new LinkedHashSet <>();
9941003
995- for (SettableValue insertValue : insertValues ) {
996- columns .add (insertValue .getIdentifier ().toString ());
997- }
1004+ outboundRow .forEach ((k , v ) -> {
1005+
1006+ if (v .hasValue ()) {
1007+ columns .add (k );
1008+ }
1009+ });
9981010
9991011 BindableOperation bindableInsert = dataAccessStrategy .insertAndReturnGeneratedKeys (table , columns );
10001012
@@ -1008,9 +1020,11 @@ private <MR> FetchSpec<MR> exchange(Object toInsert, BiFunction<Row, RowMetadata
10081020
10091021 Statement statement = it .createStatement (sql ).returnGeneratedValues ();
10101022
1011- for (SettableValue settable : insertValues ) {
1012- bindableInsert .bind (statement , settable );
1013- }
1023+ outboundRow .forEach ((k , v ) -> {
1024+ if (v .hasValue ()) {
1025+ bindableInsert .bind (statement , k , v );
1026+ }
1027+ });
10141028
10151029 return statement ;
10161030 };
0 commit comments