How can I treat the result of a query with joined tables like coming from a single table and map it to one single object?

I am doing my first steps with JDBI 3.45.1 and I have successfully managed to read data from single tables of a PostgreSQL database using handles. Unfortunately, I failed to read data from queries which join tables.

I read the chapter about joins of the JDBI development documentation and learnt about JoinRowMapper and ResultBearing#reduceRows() and reduceResultSet(), but what I would like to achieve is much more simple: I do not want to create objects and mappers for each table which is part of the join - I would just like to execute the query and map the results to a single object, treating the result like it would come from a single table.

What I basically tried was this:

Optional<StatusAndAutor> statusAndAuthor = jdbi.withHandle(
         handle -> handle.registerRowMapper(StatusAndAutor.class, 
                                            ConstructorMapper.of(StatusAndAutor.class))
               .createQuery("""
                     select r.status, c.author
                         from public.test_result r
                          join public.test_case c on r.test_case_id = c.id
                        limit 1
                        """))
            .mapTo(StatusAndAutor.class)
            .findOne();

Obviously, I am using JDBI in the wrong way here, as this leads to an exception:

Exception in thread "main" org.jdbi.v3.core.statement.UnableToCreateStatementException: org.postgresql.util.PSQLException: This connection has been closed. [statement:"select r.status, c.author
    from public.test_result r
    join public.test_case c on r.test_case_id = c.id
    limit 1
", arguments:{positional:{}, named:{}, finder:[]}]
    at org.jdbi.v3.core.statement.SqlStatement.internalExecute(SqlStatement.java:1801)
    at org.jdbi.v3.core.result.ResultProducers.lambda$createResultBearing$3(ResultProducers.java:95)
    at org.jdbi.v3.core.result.internal.ResultSetSupplier.get(ResultSetSupplier.java:55)
    at org.jdbi.v3.core.result.internal.ResultSetResultIterator.<init>(ResultSetResultIterator.java:50)
    at org.jdbi.v3.core.result.internal.ResultSetResultIterable.iterator(ResultSetResultIterable.java:51)
    at org.jdbi.v3.core.result.ResultIterable.findOne(ResultIterable.java:193)
    at org.guetter.Main.main(Main.java:23)
Caused by: org.postgresql.util.PSQLException: This connection has been closed.

I am a bit puzzled about the fact that the PostgreSQL connection is unexpectedly closed here, but this always happens when I read joined data and never happens when I read data from a single table.

Of course, I could try to go for the suggestions from the development documentation and create all the boilerplate code which necessary for that. But when I think about how easy and streamlined the use of JDBI in other scenarios can be, I wonder if there is not really a more simple way to achieve what I want.

So is there really no simple way to map the result of a query with joins to one single object?

Upvotes: 0

Views: 67

Answers (0)

Related Questions