There are many ways to materialize a nested collection with SQL and / or with jOOQ. I just look through some of them:
Using Unions
If you do not deeply nest these collections, denormalizing (smoothing) your results with JOIN can do the trick for you without adding too much overhead because the data is duplicated. Essentially, you will write:
Map<ExperimentRecord, Result<Record>> map = DSL.using(configuration) .select() .from(EXPERIMENT) .join(TAGS) .on(...) .fetchGroups(EXPERIMENT);
The above map contains experiment records as keys and nested collections containing all tags as values.
Creating Two Queries
If you want to materialize a complex graph of objects, using joins may no longer be optimal. Instead, you probably want to collect data in your client from two different queries:
Result<ExperimentRecord> experiments = DSL.using(configuration) .selectFrom(EXPERIMENT) .fetch();
and
Result<TagsRecord> tags = DSL.using(configuration) .selectFrom(TAGS) .where(... restrict to the previous experiments ...) .fetch();
And now combine the two results in your client memory, for example
experiments.stream() .map(e -> new ExperimentWithTags( e, tags.stream() .filter(t -> e.getId().equals(t.getExperimentId())) .collect(Collectors.toList()) ));
source share