Code review comment: Afaik a method lambda should also work (if not I'm happy to learn that ;)), so you wouldn't need to change that part.

Code before review:
public SinkRuntimeProvider getSinkRuntimeProvider(Context context) {
final SerializationSchema<RowData> keySerialization =
createSerialization(context, keyEncodingFormat, keyProjection, keyPrefix);
final SerializationSchema<RowData> valueSerialization =
createSerialization(context, valueEncodingFormat, valueProjection, null);
final KafkaSinkBuilder<RowData> sinkBuilder = KafkaSink.builder();
final List<LogicalType> physicalChildren = physicalDataType.getLogicalType().getChildren();
if (transactionalIdPrefix != null) {
sinkBuilder.setTransactionalIdPrefix(transactionalIdPrefix);
}
final KafkaSink<RowData> kafkaSink =
sinkBuilder
.setDeliverGuarantee(deliveryGuarantee)
.setBootstrapServers(
properties.get(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG).toString())
.setKafkaProducerConfig(properties)
.setRecordSerializer(
new DynamicKafkaRecordSerializationSchema(
topic,
partitioner,
keySerialization,
valueSerialization,
getFieldGetters(physicalChildren, keyProjection),
getFieldGetters(physicalChildren, valueProjection),
hasMetadata(),
getMetadataPositions(physicalChildren),
upsertMode))
.build();
if (flushMode.isEnabled() && upsertMode) {
return (DataStreamSinkProvider)
dataStream -> {
final boolean objectReuse =
dataStream
.getExecutionEnvironment()
.getConfig()
.isObjectReuseEnabled();
final ReducingUpsertSink<?> sink =
new ReducingUpsertSink<>(
kafkaSink,
physicalDataType,
keyProjection,
flushMode,
objectReuse
? (rowData) ->
createRowDataTypeSerializer(
context,
dataStream
.getExecutionConfig())
.copy(rowData)
: rowData -> rowData);
final DataStreamSink<RowData> end = dataStream.sinkTo(sink);
if (parallelism != null) {
end.setParallelism(parallelism);
}
return end;
};
}
return SinkProvider.of(kafkaSink, parallelism);
}

Line under review: .copy(rowData)

Code after addressing the review:
public SinkRuntimeProvider getSinkRuntimeProvider(Context context) {
final SerializationSchema<RowData> keySerialization =
createSerialization(context, keyEncodingFormat, keyProjection, keyPrefix);
final SerializationSchema<RowData> valueSerialization =
createSerialization(context, valueEncodingFormat, valueProjection, null);
final KafkaSinkBuilder<RowData> sinkBuilder = KafkaSink.builder();
final List<LogicalType> physicalChildren = physicalDataType.getLogicalType().getChildren();
if (transactionalIdPrefix != null) {
sinkBuilder.setTransactionalIdPrefix(transactionalIdPrefix);
}
final KafkaSink<RowData> kafkaSink =
sinkBuilder
.setDeliverGuarantee(deliveryGuarantee)
.setBootstrapServers(
properties.get(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG).toString())
.setKafkaProducerConfig(properties)
.setRecordSerializer(
new DynamicKafkaRecordSerializationSchema(
topic,
partitioner,
keySerialization,
valueSerialization,
getFieldGetters(physicalChildren, keyProjection),
getFieldGetters(physicalChildren, valueProjection),
hasMetadata(),
getMetadataPositions(physicalChildren),
upsertMode))
.build();
if (flushMode.isEnabled() && upsertMode) {
return (DataStreamSinkProvider)
dataStream -> {
final boolean objectReuse =
dataStream
.getExecutionEnvironment()
.getConfig()
.isObjectReuseEnabled();
final ReducingUpsertSink<?> sink =
new ReducingUpsertSink<>(
kafkaSink,
physicalDataType,
keyProjection,
flushMode,
objectReuse
? createRowDataTypeSerializer(
context,
dataStream.getExecutionConfig())
::copy
: rowData -> rowData);
final DataStreamSink<RowData> end = dataStream.sinkTo(sink);
if (parallelism != null) {
end.setParallelism(parallelism);
}
return end;
};
}
return SinkProvider.of(kafkaSink, parallelism);
}