Search code examples
mysqlspring-bootjooq

How to map jooq result to their respective entities


I have this SQL query:

select question.*, 
  question_option.id 
from question 
left join question_option on question_option.question_id = question.id;

How do I map the result obtained to the entity. so that the expected result should be like Can anyone give the sample code for getting the result as above

{
"id": 2655,
"type": "MCQSingleCorrect",
"difficultyLevel": "Advanced",
"question": "Which country are you from?",
"answer": null,
"marks": 1.5,
"negativeMarks": 0.5,
"hint": null,
"explanation": null,
"booleanAnswer": null,
"passage": null,
"isPassageQuestion": null,
"audioFile": null,
"videoFile": null,
"questionFiles": [],
"tags": [],
"updatedAt": "2021-12-21T11:57:03.229136Z",
"createdAt": "2021-12-21T11:57:03.229098Z",
"questionOptions": [
    {
        "id": 2719,
        "option": "India",
        "index": 1,
        "correct": false,
        "blank": null
    },
    {
        "id": 2720,
        "option": "Newzealand",
        "index": 1,
        "correct": false,
        "blank": null
    },
    {
        "id": 2721,
        "option": "England",
        "index": 1,
        "correct": true,
        "blank": null
    },
    {
        "id": 2722,
        "option": "Australia",
        "index": 1,
        "correct": false,
        "blank": null
    }
]}

Solution

  • I'm answering from the perspective of our comments discussion, where I suggested you don't need JPA in the middle, because you can do every mapping / projection with jOOQ directly. In this case, if you're targeting a JSON client, why not just use SQL/JSON, for example? Rather than joining, you nest your collection like this:

    ctx.select(jsonObject(
          key("id", QUESTION.ID),
          key("type", QUESTION.TYPE),
          ..
          key("questionOptions", jsonArrayAgg(jsonObject(
            key("id", QUESTION_OPTION.ID),
            key("option", QUESTION_OPTION.OPTION),
            ..
          )))
        ))
       .from(QUESTION)
       .leftJoin(QUESTION_OPTION)
       .on(QUESTION_OPTION.QUESTION_ID.eq(QUESTION.ID))
       // Assuming you have a primary key here.
       // Otherwise, add also the other QUESTION columns to the GROUP BY clause
       .groupBy(QUESTION.ID)
       .fetch();
    

    This will produce a NULL JSON array if a question doesn't have any options. You can coalesce() it to an empty array, if needed. There are other ways to achieve the same thing, you could also use MULTISET if you don't actually need JSON, but just some hierarchy of Java objects.

    As a rule of thumb, you hardly ever need JPA in your code when you're using jOOQ, except if you really rely on JPA's object graph persistence features.