Fetching a result set into a TYPE and providing addition information

40 views
Skip to first unread message

Max Kremer

unread,
Dec 23, 2018, 11:28:18 PM12/23/18
to jOOQ User Group
Hi,

  Consider the following typical query execution. I am populating a JPA annotated POJO called MyRow
   
               d.select( ..)
                .from(  ... ).as("S")
                .where( ... )
                .groupBy(groupByFields)
                .fetchInto(MyRow.class);

What I need to do is pass additional information to the MyRow constructor. How can this be achieved?

For example let's say I have a class called MyRowParserHelper that is used by the MyRow class. I need to pass an instance of the  MyRowParserHelper
(it can be the same instance) to each instance of the MyRow class created by the fetchInto method. Is this possible?

Daniele Antonini

unread,
Dec 24, 2018, 3:26:27 AM12/24/18
to jOOQ User Group
Hi,

My 2 cents: fetchInto() is a "predefined map method" . If you need more control, or use custom logic, as you described, you can use map() method instead.

Cheers

Max Kremer

unread,
Dec 24, 2018, 8:28:52 AM12/24/18
to jooq...@googlegroups.com
Thanks Daniel. This makes sense of course, however if I use plain old map I have to handle populating the fields of the pojo, something fetchInto takes care of. I want to have my cake and eat it too ;)

--
You received this message because you are subscribed to a topic in the Google Groups "jOOQ User Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jooq-user/f4u7FfAyyFY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jooq-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Lukas Eder

unread,
Dec 27, 2018, 4:00:38 AM12/27/18
to jooq...@googlegroups.com
Hi Max,

The DefaultRecordMapper supports mapping things into a pre-existing instance, so you can use it in two ways:

- By specifying the Class<E> reference, in case of which you currently cannot hook into the instantiation of that class
- By specifying <E> instance directly, in case of which you're in control of that

So, just write 

   .fetchInto(r -> r.into(new MyRow(helper)));

See:

I hope this helps
Lukas

--
You received this message because you are subscribed to the Google Groups "jOOQ User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+...@googlegroups.com.

Max Kremer

unread,
Dec 27, 2018, 11:52:38 AM12/27/18
to jOOQ User Group
AWESOME!!!!! Thanks again Lukas.

Max Kremer

unread,
Dec 27, 2018, 9:07:13 PM12/27/18
to jOOQ User Group
Follow up. Is it possible to do the above using a plain string SQL query and not building the query "Jooq Style".  I dont see any RecordMapper examples on DSLContext.fetch(String SQL) type queries....

Lukas Eder

unread,
Dec 28, 2018, 4:56:50 AM12/28/18
to jooq...@googlegroups.com
Just wrap your SQL string in DSLContext.resultQuery(...)

Max Kremer

unread,
Dec 29, 2018, 2:30:55 PM12/29/18
to jOOQ User Group
Hi

Correction.

.fetchInto(r -> r.into(new MyRow(helper)));
vs 
.fetchInto(MyRow.class);


The RowMapper example above should read 

.fetch(r -> r.into(new MyRow(helper)));



Lukas Eder

unread,
Jan 2, 2019, 7:59:21 AM1/2/19
to jooq...@googlegroups.com
Yes of course, thanks for the correction

Max Kremer

unread,
Jan 16, 2019, 4:16:53 PM1/16/19
to jOOQ User Group
Hey, sorry for reviving this thread but i noticed some strange behaviour.

I get an exception:
   
No matching constructor found on type class models.MyRow for record org.jooq.impl.DefaultRecordMapper

when using .fetch(r -> r.into(new MyRow(helper)));

Why would it be looking for a constructor when I'm passing in instance of MyRow? 

This issue is resolved when I add a default constructor:

public MyRow()  { }

Again, strange since I'm passing an already constructed instance to the record mapper. Could you please shed some light on this?

Lukas Eder

unread,
Jan 17, 2019, 1:06:22 AM1/17/19
to jooq...@googlegroups.com
Hi Max,

I would need a more complete example to help reproduce this issue.

Thanks,
Lukas

Max Kremer

unread,
Jan 17, 2019, 11:54:43 AM1/17/19
to jOOQ User Group

Hi Lukas,

  Here is a simple example to recreate the issue:


The schema
CREATE TABLE foo as ( id integer, name text);

INSERT INTO foo values
(1, 'foo'),
(2, 'bar'), (3, 'baz');


The pojo with annotations:

package models;


import javax.persistence.Column;


public class Foo {

private String name;
private int id;
private String helper;

       //NO default constructor
public Foo(String helper) {
this.helper = helper;
}
public String getName() {
return name;
}

public int getId() {
return id;
}
@Column(name="name")
public void setName(String name) {
this.namename;
}
public int getId() {
return id;
}
@Column(name="id")
public void setId(int id) {
this.id = id;
}
}


The code that throws the exception (I've glossed over the part that gets the dslcontext, i dont think its important here... )

DSLContext d;
...


d
.resultQuery("select id, name from foo" ).fetch(r -> r.into(new Foo("helper")));



The above code throws:
org.jooq.exception.MappingException: No matching constructor found on type class models.Foo for record org.jooq.impl.DefaultRecordMapper@3b059fb0

However if I add a default constructor to class Foo everything works.

public Foo() {
    //empty default constructor
}


Again I find this strange because I'm providing the mapper an instance of my class, why does it need to care about the constructor? Hope this example helps.

-Max

Lukas Eder

unread,
Jan 21, 2019, 6:27:54 AM1/21/19
to jooq...@googlegroups.com
Hi Max,

I'm afraid I can't get your example to compile. It has two getId() getters, which is not valid Java. To rule out any possible testing side effects on your side, would you mind providing an MCVE (minimal complete verifiable example) from this template here:

Thank you very much,
Lukas
Reply all
Reply to author
Forward
0 new messages