Lately I have encountered a really strange memory leak. I would appreciate if someone helps me resolve it.
public Mono<Boolean> insertOrders(List<ClientOrder> orders) {
if (orders.isEmpty()) {
return Mono.just(true);
} else {
var sqlBuilder = new StringBuilder().append(OrderQueries.INSERT_ORDERS_START);
for (var i = 0; i < orders.size(); i++) {
var order = orders.get(i);
sqlBuilder.append(String.format(
OrderQueries.INSERT_ORDERS_PARAMS,
order.getUserId(),
order.getUserName(),
order.getCustomerEmail(),
order.getCustomerMobile(),
order.getAmount(),
order.getCreateDate(),
order.getStatusChangeDate(),
i == orders.size() - 1 ? ';' : ','
));
}
return this.databaseClient.sql(sqlBuilder.toString()).fetch().rowsUpdated()
.doOnError(log::error)
.map(rows -> rows == orders.size());
}
}
And when i perform a heapdump I can see that the reference to the string of the query is stored and the sql queries are never cleared by the GC.
OrderDao(ConnectionFactory connectionFactory){
this.databaseClientNamed = DatabaseClient.builder().connectionFactory(connectionFactory).namedParameters(true).build();
this.databaseClient = DatabaseClient.builder().connectionFactory(connectionFactory).namedParameters(false).build();
}
As @ControlAltDel has mentioned the problem was with spring caching the sql statements. So as I am not using the prepared statement for this particular case and the query is very big 55K inserts. The workaround in that particular case was using another database client without namedParamenters (which was caching the result) I don't reccomend this solution to anyone. But this would be good for anyone that finds out some sql queries in Heap. NamedParameterExpander is caching everything you execute.