Wednesday, June 8, 2022
HomeProgrammingBy no means Once more Neglect to Name .execute() in jOOQ –...

By no means Once more Neglect to Name .execute() in jOOQ – Java, SQL and jOOQ.


jOOQ’s DSL, like all fluent API, has one huge caveat. It’s very straightforward to overlook to name .execute(). And if you do, chances are high, you’re going to be watching your code for minutes, as a result of all the pieces seems excellent:

ctx.insertInto(T)
   .columns(T.A, T.B)
   .values(1, 2);

Staring… staring… staring… Why is it not inserting that row?

“Aaaah, not once more!!”

That is the way it’s performed:

ctx.insertInto(T)
   .columns(T.A, T.B)
   .values(1, 2)
   .execute();

In precept, this type of mistake can occur with any fluent API. E.g. StringBuilder

sb.append("a").append("b"); // Not consuming the outcome

Or streams:

Stream.of(1, 2).peek(System.out::println); // Not a lot peeking

Nevertheless it often doesn’t occur as a lot, as a result of the distinction to jOOQ is that

  • jOOQ’s DML statements (INSERT, UPDATE, DELETE, MERGE) and DDL statements (CREATE, ALTER, DROP, TRUNCATE), and some different produce a facet impact
  • That facet impact is the one factor we care about. The outcome (the replace depend) is generally irrelevant

And as such, we don’t care about the results of execute(), which is an int. Nobody forgets to name fetch() on a jOOQ ResultQuery:

ctx.choose(T.A, T.B)
   .from(T); // Nicely duh

As a result of with out calling fetch() or one thing related, we’re not getting any outcomes, and we wish the outcomes, identical to with the StringBuilder or the Stream. However we don’t need the execute() outcome.

As such, even we, when writing jOOQ’s integration checks, sometimes overlook to name this foolish little technique.

No extra!

When it occurred once more this week…

… I lastly created a problem to consider it: https://github.com/jOOQ/jOOQ/points/11718. And I created a problem to surprise if JetBrains may do one thing about it: https://youtrack.jetbrains.com/subject/IDEA-265263

And so they already can! Aside from the org.jetbrains.annotations.Contract annotation, which is there for exactly this cause, apparently, it’s additionally attainable to mimick the JSR-305 @CheckReturnValue annotation on each technique “whose return worth must be checked” (i.e. a way that has no facet impact, or whose facet impact is to mutate solely “this“).

I added this annotation, I added it to all of the related jOOQ API, which was a little bit of yak shaving (https://github.com/jOOQ/jOOQ/commit/f2b529a2305f8c5f8d037776687887a5acd50b11) and voilà

image

As you possibly can see, IntelliJ now warns the consumer at any time when they overlook to eat the results of any of jOOQ’s DSL strategies (by calling execute(), passing it to some technique that consumes it, and many others.)

Thanks once more to Tagir Valeev from JetBrains for strolling me by this and even enhancing the @Contract annotation, which jOOQ would possibly use in a future model.



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments