Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
    }

}
like image 741
Ranish Karim Avatar asked Aug 05 '15 10:08

Ranish Karim


1 Answers

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

query.from(modelA)
     .leftJoin(modelA.modelB, modelB)
     ...
like image 142
Timo Westkämper Avatar answered Oct 06 '22 11:10

Timo Westkämper