Idiomatic nullability with fetchOne().map()

60 views
Skip to first unread message

Ben Hood

unread,
Jun 27, 2014, 11:05:19 AM6/27/14
to jooq...@googlegroups.com
Hey Lukas,

Using 3.4 API on JDK8 I was wondering what the idiomatic way is of
chaining a map() onto a fetchOne() that could return null. Using
fetchOneInto(classDef) seems to handle this internally, which works in
a number of cases, but the map() API is more flexible. Or do you have
to use some kind of Scala-esque Option?

Cheers,

Ben

Lukas Eder

unread,
Jun 27, 2014, 11:10:38 AM6/27/14
to jooq...@googlegroups.com
Ben, I'm sorry, but I don't really know what you're asking me :-)
What are you looking for? Can you provide an example?



--
You received this message because you are subscribed to the Google Groups "jOOQ User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ben Hood

unread,
Jun 27, 2014, 11:16:06 AM6/27/14
to jooq...@googlegroups.com
Yeah, sorry for being so abstract :-(

Here's the code that works for me:

return db.execute(ctx -> {
Record r = ctx.select().
from(PREFIXES).
where(PREFIXES.NATIONAL.eq(prefix + "")).
fetchOne();
if (r == null) {
return null;
}
return r.map(PREFIX_MAPPER);
});


This query can only ever return 0 or 1 rows. So I was wondering how to
get rid of the check for the null Record instance.

Does that make sense?

Lukas Eder

unread,
Jun 27, 2014, 11:19:15 AM6/27/14
to jooq...@googlegroups.com
Ah, maybe, you're looking for something like this?

Optional<MyPrefixClass> result =
DSL.using(configuration)
   .select(A)
   .from(TABLE)
   .fetch()
   .map(PREFIX_MAPPER)
   .stream()
   .findFirst();


Ben Hood

unread,
Jun 27, 2014, 11:34:36 AM6/27/14
to jooq...@googlegroups.com
On Fri, Jun 27, 2014 at 4:19 PM, Lukas Eder <lukas...@gmail.com> wrote:
> Ah, maybe, you're looking for something like this?
>
> Optional<MyPrefixClass> result =
> DSL.using(configuration)
> .select(A)
> .from(TABLE)
> .fetch()
>
> .map(PREFIX_MAPPER)
>
> .stream()
>
> .findFirst();

Very nice!

I think I might just give up writing code myself and get you to write
my app via the mailing list - do you also write mailing list parsers
:-)

So for note, I ended up using this to get rid of the check for null:

return db.execute(ctx ->
ctx.select().
from(PREFIXES).
where(PREFIXES.NATIONAL.eq(prefix + "")).
fetch().
map(PREFIX_MAPPER).
stream().
findFirst().
orElse(null)
);

But just to get rid of that funny Optional thingy.

Lukas Eder

unread,
Jun 27, 2014, 11:40:26 AM6/27/14
to jooq...@googlegroups.com
2014-06-27 17:34 GMT+02:00 Ben Hood <0x6e...@gmail.com>:
On Fri, Jun 27, 2014 at 4:19 PM, Lukas Eder <lukas...@gmail.com> wrote:
> Ah, maybe, you're looking for something like this?
>
> Optional<MyPrefixClass> result =
> DSL.using(configuration)
>    .select(A)
>    .from(TABLE)
>    .fetch()
>
>    .map(PREFIX_MAPPER)
>
>    .stream()
>
>    .findFirst();

Very nice!

I think I might just give up writing code myself and get you to write
my app via the mailing list - do you also write mailing list parsers
:-)

I think the usual Data Geekery rates are somewhere in the license text:

;-)
 
So for note, I ended up using this to get rid of the check for null:

return db.execute(ctx ->
        ctx.select().
            from(PREFIXES).
            where(PREFIXES.NATIONAL.eq(prefix + "")).
            fetch().
            map(PREFIX_MAPPER).
            stream().
            findFirst().
            orElse(null)
    );

Nice. I always like it when statements end with "OR ELSE!!!" ;-)

But I like that alternative of yours. It's a sign that some jOOQ features can slowly transition towards more idiomatic Java 8 code. There was this blog post here, that also showed how more complex transformations on jOOQ records can be performed once the org.jooq.Result<R> is transformed into a JDK Stream<R>:

What's that db.execute thing, btw?

Ben Hood

unread,
Jun 27, 2014, 12:04:59 PM6/27/14
to jooq...@googlegroups.com
On Fri, Jun 27, 2014 at 4:40 PM, Lukas Eder <lukas...@gmail.com> wrote:
> I think the usual Data Geekery rates are somewhere in the license text:
> http://www.jooq.org/legal/licensing

Probably a good idea - this would probably save the world from me
using the JOOQ API to subvert PostgreSQL into doing multi-column pivot
queries, when you could just use Oracle natively for that kind of
thing :-)

> Nice. I always like it when statements end with "OR ELSE!!!" ;-)

Actually I'm going to take everything I ever said back (thank god I'm
transactional) - you've inadvertently convinced me of a better way.
I've just actually read the Optional API (first time I've RFTM'ed
something in a while) and it has this neat thing called orElseThrow().
With this I can change my API to

Optional<Prefix> getPrefix(prefix);

And then at a higher layer I can do this:

return api.getPrefix(prefix).orElseThrow(ResourceNotFoundException::new);

Every day is a school day :-)

> But I like that alternative of yours. It's a sign that some jOOQ features
> can slowly transition towards more idiomatic Java 8 code. There was this
> blog post here, that also showed how more complex transformations on jOOQ
> records can be performed once the org.jooq.Result<R> is transformed into a
> JDK Stream<R>:
> http://blog.jooq.org/2014/04/11/java-8-friday-no-more-need-for-orms/

Yes, I liked that article - FWIW back in the day, I did really like
using the JOOQ API with Scala to get a really terse and expressive
handle on non-trival DB queries. Hopefully some of that Kool-Aid can
be drunk with Java.

> What's that db.execute thing, btw?

Just some glue from my project, nothing really to write home about,
but here's the definition in any case:
https://gist.github.com/0x6e6562/95844ed3ef981a0c227b

Lukas Eder

unread,
Jul 1, 2014, 2:44:59 AM7/1/14
to jooq...@googlegroups.com
Hi Ben,

2014-06-27 18:04 GMT+02:00 Ben Hood <0x6e...@gmail.com>

> What's that db.execute thing, btw?

Just some glue from my project, nothing really to write home about,
but here's the definition in any case:
https://gist.github.com/0x6e6562/95844ed3ef981a0c227b

Thanks for sharing. I see, it's similar to what we've been doing for jOOQ 3.4's new transaction API (which I've noticed is still undocumented in the manual...)

Cheers
Lukas 

Ben Hood

unread,
Jul 1, 2014, 10:10:32 AM7/1/14
to jooq...@googlegroups.com
On Tue, Jul 1, 2014 at 7:44 AM, Lukas Eder <lukas...@gmail.com> wrote:
> Thanks for sharing. I see, it's similar to what we've been doing for jOOQ
> 3.4's new transaction API (which I've noticed is still undocumented in the
> manual...)

Oh really, I hadn't seen this new API, I'll check it out. That DB
thing is just some glue that I've carried around in various different
projects where I've used JOOQ - that variant I posted was just updated
for JDK8. Previously I've used Scala and named interfaces in JDK7.
Reply all
Reply to author
Forward
0 new messages