Detect Accidental Blocking Calls when Using R2DBC

A while ago, jOOQ has added the org.jetbrains:annotations dependency to the jOOQ API, in order to annotate return types with nullability information. For example, the entire DSL is non-nullable:

public interface SelectWhereStep<R extends Record>
extends SelectConnectByStep<R> {

    @NotNull @CheckReturnValue
    SelectConditionStep<R> where(Condition condition);

    // ...

It makes sense to give this guarantee especially to kotlin users, as they can get rid of some of the more complex types involving things like Select!<Record!>, which now turns into at least Select<Record!>. Notice also the @CheckReturnValue annotation, which IntelliJ uses for some introspections.

Other cases are more obvious, such as:

public interface ResultQuery<R extends Record> 
extends Fields, Query, Iterable<R>, Publisher<R> {

    R fetchOne() throws TooManyRowsException;

    R fetchSingle() throws NoDataFoundException, TooManyRowsException;

    // ...

The difference between these two types of fetch methods is that fetchOne() expects 0-1 resulting records, whereas fetchSingle() expects exactly 1 record. Both throw exceptions otherwise, but only the latter can guarantee a non-nulllable record value.

But wait, what’s this @Blocking annotation?

In jOOQ 3.17, we’ve added the org.jetbrains.annotations.Blocking annotation to all jOOQ API that executes a query on top of JDBC. This doesn’t affect users of JDBC based jOOQ queries at all, but if you’re using R2DBC for reactive querying with jOOQ, you might be tempted to accidentally call one of jOOQ’s many many blocking execution methods.

No more! IntelliJ will now complain about such a call being inappropriate:


At least as soon as you enable the introspection:


It is up to you to decide whether you want this to be a warning or an error, but at least, you’ll notice that you’re about to do something wrong.

Eclipse does not yet support this kind of introspection. If you agree it should, you could upvote this issue here:

Leave a Reply