micronaut-data icon indicating copy to clipboard operation
micronaut-data copied to clipboard

Hook to customize PreparedStatements before they are executed

Open mikehearn opened this issue 10 months ago • 7 comments

Feature description

Some database drivers like Oracle's have useful features on PreparedStatement. One example is continuous query notification. Micronaut Data today can't be combined with these, because there's no way to get access to a PreparedStatement before it gets executed. It'd be useful to have a hook point which statements could be passed through after they're generated but before they're executed.

mikehearn avatar Feb 05 '25 17:02 mikehearn

What would you like to set there?

dstepanov avatar Feb 07 '25 08:02 dstepanov

Two things:

  1. A pre-hook to edit the SQL before it's sent (useful in some advanced scenarios)
  2. Ability to call OraclePreparedStatement.setDatabaseChangeRegistration on the statement after it's been created.

mikehearn avatar Feb 10 '25 11:02 mikehearn

can you not instrument the datasource?

graemerocher avatar Feb 10 '25 12:02 graemerocher

Maybe, but that sounds like a lot more work? I've not seen it done before, how much effort would it be to write a DataSource that adds such features?

mikehearn avatar Feb 10 '25 12:02 mikehearn

this is how micrometer observation does it https://github.com/micronaut-projects/micronaut-micrometer/tree/5.10.x/micrometer-observation-datasource/src/main/java/io/micronaut/micrometer/observation/datasource not sure of the quantity of work involved

graemerocher avatar Feb 10 '25 12:02 graemerocher

It looks like it's using this library that makes intercepting and rewriting calls into the driver easy:

https://jdbc-observations.github.io/datasource-proxy/docs/current/user-guide/#about

I can try that. Is there a way to avoid collisions with micronaut-micrometer if multiple libraries want to proxy a DataSource? This code looks suspicious:

@Override
    public int getOrder() {
        // There is another listener in micronaut-tracing with HIGHEST_PRECEDENCE order
        // so this is just to avoid beans with the same order
        return Ordered.HIGHEST_PRECEDENCE + 1;
    }

You can order yourself higher than the highest precedence.

It feels like this library could be wrapped by Micronaut SQL because it appears the proxying is somewhat immutable. I can add QueryExecutionListeners after the fact and that might be enough, but other stuff is set using a builder. It'd be convenient if there was only one proxy and the listeners were combined using the injector.

I'll experiment with that library.

mikehearn avatar Feb 10 '25 13:02 mikehearn

HIGHEST_PRECEDENCE is a negative value

graemerocher avatar Feb 10 '25 13:02 graemerocher