Search code examples
javasqljooq

How can one see the SQL statements that jOOQ executes at Compile Time?


I use jOOQ to query/insert/update data from/into a table.

Is there a way to see the SQL statements that JOOQ executes at Compile Time instead of Run Time Logging?

The following answer shows them at run time. How can one see the SQL statements that jOOQ executes?

This tool only converts various SQL dialects. https://www.jooq.org/translate/


Solution

  • Statically evaluating a jOOQ query

    While it might be possible to build some IDE plugins that are capable of evaluating some static-ish jOOQ statements, remember that in principle and by design, every jOOQ query is a dynamic SQL query. When you write something as simple as:

    Result<?> r = ctx.select(T.A, T.B).from(T).fetch();
    

    What the JVM sees (roughly) is:

    Field<?> a = T.A;
    Field<?> b = T.B;
    Field<?>[] select = { a, b };
    SelectFromStep<?> s1 = ctx.select(select);
    Table<?> t = T;
    SelectWhereStep<?> s2 = s1.from(t);
    Result<?> r = s2.fetch();
    

    Of course, no one is using jOOQ this way. The DSL was designed to produce call chains that look almost like SQL through its fluent API design. So, your query looks like it's static SQL (which could be evaluated in an IDE), but it is not. And you will often use the dynamic SQL capabilities, e.g.

    Result<?> r = ctx
        .select(T.A, T.B)
        .from(T)
        // Dynamic where clause
        .where(someCondition ? T.A.eq(1) : T.B.gt(2))
        .fetch();
    

    There's no way an IDE could evaluate all this, including all of your SPI implementations, such as the ExecuteListener or the VisitListener, so again, even if it worked for some cases, it would work poorly for many others.

    You'll have to execute your query to see the actual SQL (for that specific execution). Or, you put a breakpoint on your fetch() call, and evaluate the query object upon which fetch() is called in the debugger.

    The underlying, actual problem

    Whenever I see this question, I think there's an underlying actual problem that manifests in this desire of running the jOOQ query outside of your Java code. The problem is that your code seems to be hard to integration test.

    This can't be fixed easily, but it is a good reminder that when you start from scratch, you make all of your SQL (jOOQ or not) easily integration testable using:

    1. Something like testcontainers
    2. By separating concerns and moving your SQL logic in an appropriate layer that can be easily integration tested independently of any other logic (UI, etc.)

    With such an approach, you will be able to test your jOOQ queries in a much better feedback cycle, in case of which you probably won't even think of running the jOOQ query outside of your Java code again, at least most of the time.