QueryDsl - 关联实体

时间:2018-02-01 17:25:28

标签: java spring hibernate jpa querydsl

一些简单的实体:

enter image description here

技术堆栈

  • Hibernate 5.2.10
  • QueryDsl(jpa,apt)4.1.4
  • Spring Boot 1.5.6
  • Spring Data JPA(因此,使用存储库)
  • 存储库扩展QueryDslPredicateExecutor

我想用这种效果进行查询:

  

为MeetupCampaigns选择以下 BOTH 的关联Meetup:
    * MeetupCampaign.id = x
    * MeetupCampaign.approvalStatus = y

重要的是,BOTH必须是真的

我能够获得 条件为真,但无法过滤两者的结果

我将谓词传递给repository.findAll()

我不确定是使用MeetupRepository还是MeetupCampaignRepository

当提取 MeetupCampaigns时,此谓词有效:

meetupCampaign.approvalStatus.eq(approvalStatus).and(meetupCampaign.campaign.id.eq(campaignId));

但是当我尝试获取Meetups

时间接失败
meetup.meetupCampaigns.any().campaign.id.eq(campaignId).and(meetup.meetupCampaigns.any().approvalStatus.eq(approvalStatus));

在这种情况下,我得到任何 条件为真的MeetupCampaign

考虑这个数据集:

<!-- Should be selected -->
    <meetup_campaign id="600" meetup_id="500" campaign_id="200" approval_status="ACCEPTED"/>
    <meetup_campaign id="605" meetup_id="504" campaign_id="200" approval_status="ACCEPTED"/>
<!-- Rejected because meetupCampaign status declined -->
    <meetup_campaign id="601" meetup_id="501" campaign_id="200" approval_status="DECLINED"/>
<!-- Rejected because wrong campaign id -->
    <meetup_campaign id="602" meetup_id="500" campaign_id="201" approval_status="ACCEPTED"/>
    <meetup_campaign id="606" meetup_id="501" campaign_id="201" approval_status="ACCEPTED"/>
    <meetup_campaign id="603" meetup_id="502" campaign_id="201" approval_status="ACCEPTED"/>
<!-- Rejected on both counts -->
    <meetup_campaign id="604" meetup_id="503" campaign_id="201" approval_status="DECLINED"/>

请注意,应选择聚会500和504。 501是这里的重要人物。不应该选择它,因为与它关联的两个MeetupCampaigns都不符合其中一个标准。

你能帮我写这个查询吗?

更新

(简体)实体代码:

@Entity
public class Meetup {

    @Id
    @Column(nullable = false, updatable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;

    @Fetch(FetchMode.SELECT)
    @RestResource(exported = false)
    @OneToMany(mappedBy = "meetup", fetch = FetchType.EAGER, orphanRemoval = true)
    private Set<MeetupCampaign> meetupCampaigns = new HashSet<>();

}

@Entity
public class MeetupCampaign {

    @Id
    @Column(nullable = false, updatable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(nullable = false, updatable = false)
    private Campaign campaign;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(nullable = false, updatable = false)
    private Meetup meetup;

    @Enumerated(EnumType.STRING)
    private ApprovalStatus approvalStatus;

}

@Entity
public class Campaign {

    @Id
    @Column(nullable = false, updatable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;

}

1 个答案:

答案 0 :(得分:1)

Found an answer here: QueryDsl - subquery in collection expression

You can use a subquery expression to find all the meetupCampaigns with those two properties and then use the SimpleExpression.in() to find meetups related to those meetupCampaigns.

ex.

meetup.in(JPAExpressions.select(meetupCampaign.meetup).from(meetupCampaign).where(meetupCampaign.campaign.id.eq(campaignId).and(meetupCampaign.approvalStatus.eq(status))).fetchAll());