Reputation: 736
I'm new at using JOOQ and I have problem but I can't find solution. I have simple database with 2 tables: Sellers
and Clients
- sql below:
CREATE TABLE Sellers
(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(255) NOT NULL,
);
CREATE TABLE Clients
(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(255) NOT NULL,
seller_id int,
FOREIGN KEY (seller_id) REFERENCES Sellers(id)
);
Client
has foreign key
and it defines which Seller
is assigned to him.
I would like to get clients from database using JOOQ but using join()
also get Seller
object to each of client. Is it possible? If so how to do that? Here's my POJO objects:
public class Seller {
private final SimpleIntegerProperty id = new SimpleIntegerProperty();
private final SimpleStringProperty name = new SimpleStringProperty();
...
//setters and getters here
...
}
public class Client {
private final SimpleIntegerProperty id = new SimpleIntegerProperty();
private final SimpleStringProperty name = new SimpleStringProperty();
private final SimpleIntegerProperty sellerId = new SimpleIntegerProperty();
//private Seller seller; //not working
...
//setters and getters here
...
}
And here's my JOOQ code to get clients:
context.select()
.from(CLIENTS)
.join(SELLERS)
.on(CLIENTS.ID.eq(SELLERS.ID))
.fetchInto(Client.class);
What should I change to get what I want?
Upvotes: 1
Views: 1926
Reputation: 3569
check out the conversation here between Lukas Eder (the author of jOOQ) and some other jOOQ users. Garrett Wilson's use case looks very similar to yours (where you have Client
:Seller
, he has Book
:Author
).
there's quite a bit said, but by design it seems jOOQ isn't geared toward automatically hydrating a Seller
instance within your fetched Client
record. this is the classic N+1 problem associated with ORMs (i.e. multiple queries against your table of sellers triggered by a query for clients).
one proposal is to to break your join up into discrete queries:
select * from Client where ...
select * from Seller where id in (select seller_id from Client where ...)
... and then do your client.setSeller()
type logic somewhere in your application. in this case you avoid the N+1 problem, and you don't need to rely on writing custom any RecordMapper
types.
i'm no jOOQ expert, but the approach i used in the past when i had columns from hierarchical types being returned in one query worked out pretty well for me:
Record
to your domain type/POJORecordMapperProvider
and use it to create DSLContext
singleton that gets passed around to whatever components do your querying (e.g. through dependency injection)DSLContext
, compose your query and use fetchInto()
to designate your target type (which should have been accounted for in your RecordMapperProvider
)in the conversation referenced earlier, Lukas drops a link to the documentation about using custom RecordMapperProvider
instances, so this might very well be idiomatic.
hope that helps.
Upvotes: 1