Ranish Karim
Ranish Karim

Reputation: 366

QueryDSL add cross join when building predicate queries

I want to fetch data from modelA base on user which are in modelB. But its not compulsory that for every record i will have record in modelB. So when i use below code to fetch data, it return 0 records.

BooleanExpression searchCriteria = searchCriteria
          .and(
                   qModelA.modelb.user.id.eq(userId)
              )
          .and ( some other conditions as well);

modelA.findAll(searchCriteria, pageable);

When i debug i found that QueryDsl put Cross join. Can anyone tell me how to fix this, is there any way that querydsl add left join instead of cross join? below are my two models.

@Entity
public class ModelA implements Serializable {

    private Long id;
    private String label;
    private ModelB modelB;

    @Id
    @SequenceGenerator(name = "modelASeq", sequenceName = "modela_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "modelASeq")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(length = 150, nullable = false)
    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    @OneToOne(mappedBy = "modelA", cascade = CascadeType.REMOVE)
    public ModelB getModelB() {
        return modelB;
    }

    public void setModelB(ModelB modelB) {
        this.modelB = modelB;
    }

}

@Entity
public class ModelB implements Serializable {

    private Long id;
    private User user;
    private ModelA modelA;

    @Id
    @SequenceGenerator(name = "modelBSeq", sequenceName = "modelb_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "modelBSeq")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @NotNull
    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false )
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @NotNull
    @OneToOne
    @JoinColumn(name = "modela_id", nullable = false)
    public ModelA getModelA() {
        return modelA;
    }

    public void setModelA(ModelA modelA) {
        this.modelA = modelA;
    }

}

Upvotes: 6

Views: 1959

Answers (1)

Timo Westkämper
Timo Westkämper

Reputation: 22200

If you need a left join instead you will need to use explicit joins:

query.from(modelA)
     .leftJoin(modelA.modelB, modelB)
     ...

Upvotes: 1

Related Questions