Search code examples
jooq

JOOQ: fetchGroups() always returns list with only one element


I'm new to JOOQ and currently fail to map a joined query to Map<K, List<V>>: the list always only contains one element.

Here's my code:

        DSL.using(...)
            .select(ORDER.fields())
            .select(ORDER_ITEM_ARTICLE.fields())
            .from(ORDER)
            .leftOuterJoin(ORDER_ITEM_ARTICLE).on(ORDER.ID.eq(ORDER_ITEM_ARTICLE.ORDER_ID))

            // to Map<InOutOrder, List<OrderItemArticle>>
            .fetchGroups(
                r -> r.into(ORDER).into(InOutOrder.class),
                r -> r.into(ORDER_ITEM_ARTICLE).into(OrderItemArticle.class)
            )

            // map to InOutOrder
            .entrySet().stream().map( e -> {

                // e.getValue() always returns list with only 1 element?!
                e.getKey().articles = e.getValue();
                return e.getKey();
            })
            .collect(Collectors.toList())
            ;

Say I have 1 row in ORDER and 2 corresponding rows in ORDER_ITEM_ARTICLE. Running the SQL returned by .getSQL() (after .fetchGroups()), returns me 2 rows as expected, so I assumed the fetchGroups() call will populate my list with two entries as well?!

What am I missing?

Thanks!


Update:

As requested, the InOutOrder class:

public class InOutOrder extends Order {
    public List<OrderItemArticle> articles;
    public List<OrderItemOther> others;
    public List<OrderItemCost> costs;
    public List<OrderContact> contacts;
    public List<EmailJob> emailJobs;
}

So this is just an extension of the JOOQ POJO class and is used for JSON communication with the API clients...


Solution

  • fetchGroups() simply puts objects in a LinkedHashMap. You have to adhere to the usual Map contract, which means implementing equals() and hashCode(). Without it, each object you're creating (or which jOOQ is creating for you) will use identity comparison, so you get every "value" only once in the result.