Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to join @joinTable using JPASQLQuery class? #2809

Closed
eari100 opened this issue Apr 23, 2021 · 3 comments
Closed

Is it possible to join @joinTable using JPASQLQuery class? #2809

eari100 opened this issue Apr 23, 2021 · 3 comments
Labels

Comments

@eari100
Copy link

eari100 commented Apr 23, 2021

For example, when the source code is as follows

@NoArgsConstructor
@Entity
public class Summoner implements Serializable {
    @Id@Column(length=56)
    private String id;
    @Column(name="account_id", length=56)
    private String accountId;
    private int profileIconId;
    private long revisionDate;
    private String name;
    @Column(length=78)
    private String puuid;
    private long summonerLevel;

    @OneToMany
    @JoinTable(name="summoner_match",
            joinColumns = @JoinColumn(name="account_id"),
            inverseJoinColumns = @JoinColumn(name="game_id")
    )
    private List<Match> matches = new ArrayList<>();

    //...
}
@NoArgsConstructor
@Entity
public class Match {
    @Id
    @Column(name="game_id")
    private long gameId;
    private int queueId;
    private String platformId;
    private int seasonId;
    private long gameCreation;
    private long gameDuration;

    @OneToMany
    @JoinColumn(name = "game_id", referencedColumnName = "game_id")
    List<Participant> participants = new ArrayList<>();

    //...
}

I want to generate the following sql using JPASQLQuery class

-- h2 database
SELECT
    *, row_number()OVER()
FROM 
    summoner s
LEFT OUTER JOIN
    summoner_match sm
on
   s.account_id= sm.account_id
LEFT OUTER JOIN
    match m
on
   sm.game_id = m.game_id 

I tried and failed like below.

package gg.om.omgg.domain.summoner;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.querydsl.jpa.sql.JPASQLQuery;
import com.querydsl.sql.SQLExpressions;
import gg.om.omgg.domain.match.QMatch;
import gg.om.omgg.domain.participant.QParticipant;
import gg.om.omgg.web.dto.SummonerIntegrationInformationResponseDTO;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class SummonerCustomRepositoryImpl implements SummonerCustomRepository {
    // JPASQLQuery class is registered as @Bean in advance
    private final JPASQLQuery jpasqlQuery;

    @Override
    public void mySolution() {
        QSummoner summoner = QSummoner.summoner;
        QMatch match = QMatch.match;

        // How do I join summoner and summoner_match?
        jpasqlQuery
                .select(summoner, match, SQLExpressions.rowNumber().over())
                .from(summoner)                                                                                              
                .leftJoin(summoner_match).on(summoner.accountId.eq(summoner_match.accountId))
                .leftJoin(match)
                .on(summoner_match.gameId.eq(match.gameId))
                .fetch();
   }
}

(Please tell me if there is any other method provided by querydsl other than using the JPASQLQuery class.)

@jwgmeligmeyling
Copy link
Member

Just use a JPQL query and create a custom function for the "ROW_NUMBER" function. You can also use blaze-persistence-integration-querydsl-expressions to add window function support to JPA: https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/#querydsl-integration

JPASQLFunctions only serve a very specific use case and I doubt that associtation joins are supported.

@eari100
Copy link
Author

eari100 commented Apr 23, 2021

@jwgmeligmeyling
Thanks to you, I can sleep

@eari100
Copy link
Author

eari100 commented Apr 26, 2021

Seems to have found a way.
Please check if there is a problem.

    @Override
    public void mySolution() {
        QSummoner summoner = QSummoner.summoner;
        QMatch match = QMatch.match;
        // Create Qclass for @JoinTable
        QSummoner summoner_match1 = new QSummoner("summoner_match");
        QMatch summoner_match2 = new QMatch("summoner_match");

    
        jpasqlQuery
                .select(summoner, match, SQLExpressions.rowNumber().over())
                .from(summoner)                                                                                              
                .leftJoin(summoner_match1).on(summoner.accountId.eq(summoner_match1.accountId))
                .leftJoin(match).on(summoner_match2.gameId.eq(match.gameId))
                .fetch();
   }

@querydsl querydsl locked and limited conversation to collaborators Jun 23, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Projects
None yet
Development

No branches or pull requests

2 participants