Hibernate allows to inspect every SQL command and possibly returning a different SQL command before it is executed, thankfully to the StatementInspector SPI.
In our (blocking) Spring Web App we are using it to implement multi-tenancy at row level. The user authenticates and in hibernate's inspect
method we get user authentication info from the Spring SecurityContextHolder
, which we use to change the SQL and implement multi-tenancy. Everything works, as each HTTP request is bound to a specify Thread that will completely fulfill the request.
In a reactive version of the above app this doesn't work. ReactiveSecurityContextHolder
returns the asynchronous type Mono
and the hibernate's inspect
method return a sync type (String
).
Is there a similar method like inspect
in hibernate reactive to keep the similar multitenancy implementation like in the blocking version, maybe something like Mono<String> inspect(String sql);
I wasn't able to find it.
I've created an issue to keep track of this feature.
In the meanwhile, in Hibernate Reactive, you could create a wrapper around ReactiveConnection
and intercepts all the calls related to the execution of the query.
For example, you can have:
public class ConnectionInterceptor implements ReactiveConnection {
private final ReactiveConnection delegate;
public ConnectionInterceptor(ReactiveConnection delegate) {
this.delegate = delegate;
}
public CompletionStage<Void> execute(String sql) {
String newSql = convert(sql);
return delegate.execute(newSql);
}
// ... You need to implement all the other methods running a query
}
package my.example;
public class MyPool extends DefaultSqlClientPool {
public CompletionStage<ReactiveConnection> getConnection() {
return super.getConnection().thenApply( ConnectionInterceptor::new );
}
}
You can register the new pool class using the property hibernate.vertx.pool.class
:
hibernate.vertx.pool.class = my.example.MyPool
This approach will probably not work with Quarkus because it uses it's own pool and there's not a way to override it (as far as I know).