一些简单的实体:

java - QueryDsl-关联实体的多个字段上的JPA查询-LMLPHP

技术栈


休眠5.2.10
QueryDsl(jpa,apt)4.1.4
春季启动1.5.6
Spring Data JPA(因此,使用存储库)
存储库扩展QueryDslPredicateExecutor


我要查询具有这种效果:


  选择相关联的聚会,其中MeetupCampaigns满足以下两项:
    * MeetupCampaign.id = x
    * MeetupCampaign.approvalStatus = y


重要的是,两者都必须为真

我可以在其中两个条件都成立的情况下获得结果,但无法同时针对这两个条件进行过滤

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

我不确定是否要使用MeetupRepositoryMeetupCampaignRepository

仅提取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;

}

最佳答案

在这里找到答案:QueryDsl - subquery in collection expression

您可以使用子查询表达式查找具有这两个属性的所有meetupCampaigns,然后使用SimpleExpression.in()查找与那些meetups相关的meetupCampaigns

例如

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

10-05 19:04