Looking at the Sakila database I wonder how could I write a query that gets me a Country plus all Cities in the country.
I imagine it returning Result<Record2<CountryRecord,List>. Does that make sense? I might want a country plus all cities attached to it in one jooq query? I assume it might use the multiset under the covers?
MULTISET
In your particular case, it doesn't seem you need to use MULTISET
, you can just use a classic join based solution, e.g.
Map<CountryRecord, Result<CityRecord>> map = ctx
.select()
.from(CITY)
.join(COUNTRY).on(CITY.COUNTRY_ID.eq(COUNTRY.COUNTRY_ID))
.fetchGroups(COUNTRY, CITY);
It's creating a Map<CountryRecord, Result<CityRecord>>
, which is almost the same as what you requested.
MULTISET
In jOOQ 3.17, #4727 was implemented allowing to use any Table<R>
reference as a SelectField<R>
to project table expressions just like in PostgreSQL, producing the generated nominal record types instead of the strucural Record[N]
types. You can then write:
Result<Record2<CountryRecord, Result<CityRecord>>> result = ctx
.select(
// You can project any table expression here
COUNTRY,
multiset(
selectFrom(CITY)
.where(CITY.COUNTRY_ID.eq(CITY.COUNTRY_ID))
))
.from(COUNTRY)
.fetch();
This is the exact type you wanted (Result
extends List
, so I'm assuming this is fine). Different types can be created by using different kinds of ad-hoc conversion
See also: https://www.jooq.org/doc/dev/manual/sql-building/table-expressions/tables-as-selectfield/
MULTISET
Without the above means to project a generated record, you can do this to project them manually:
Result<Record2<CountryRecord, Result<CityRecord>>> result = ctx
.select(
// Manually nest all columns of a table in a nested record
row(COUNTRY.fields()).convertFrom(r -> r.into(COUNTRY)),
multiset(
selectFrom(CITY)
.where(CITY.COUNTRY_ID.eq(CITY.COUNTRY_ID))
))
.from(COUNTRY)
.fetch();
This obviously still works in jOOQ 3.17 as well