JavaSpring规范嵌套连接条件

rseugnpd  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(355)

我试图获取一个实体列表及其基于最深层字段值的关系。本机sql查询本身似乎足够简单,但我无法使用jpql或规范进行过滤。我的table的结构是 Ad -> SubmittedValue -> Configuration ,我希望能够按 Configuration 调用的实体 isSpecial . 我目前有:

@Entity
public class Ad extends BaseEntity{
    @JoinColumn(name = "user_id")
    private User user;
    @OneToMany(mappedBy = "ad")
    private List<SubmittedValue> values;
}

@Entity
/* @ToString and @EqualAndHashCode exclude "ad" */
public class SubmittedValue extends BaseEntity{
    @ManyToOne
    @JoinColumn(name = "ad_id")
    private Ad ad;
    @ManyToOne
    @JoinColumn(name = "configuration_id")
    private Configuration configuration;
    }

@Entity
public class Configuration extends BaseEntity{
    private Boolean isSpecial = false;
}

到目前为止,我已经尝试使用jpql:

@Query("select a from Ad a inner join a.values as v inner join v.configuration as c on c.isSpecial = true where a.user.id =?1")
Page<Ad> findAllBySpecialConfiguration(Pageable page, Long userId);

以及下面写的说明。它们都正确地返回了实体,但排除了 SubmittedValues 其中 isSpecial 的价值 configurationfalse 未应用于结果。以下是我的说明:

public static Specification<Ad> adSpecial(Long userId) {
    return (root, query, criteriaBuilder) -> {
      ListJoin<Ad, SubmittedValue> values = root.join(Ad_.values);
      Join<SubmittedValue, Configuration> config = values.join(SubmittedValue_.configuration);
      // config.on(criteriaBuilder.isTrue(config.get(Configuration_.isSpecial).as(Boolean.class)));
      List<Predicate> conditions = new ArrayList<>();
      conditions.add(criteriaBuilder.isTrue(config.get(Configuration_.isSpecial).as(Boolean.class)));
      conditions.add(criteriaBuilder.equal(root.get(Ad_.user).get(User_.id).as(Long.class), userId));
      return criteriaBuilder.and(conditions.toArray(new Predicate[0]));
    };
  }

谢谢和问候!

kmynzznz

kmynzznz1#

你必须改变你的产品规格

ListJoin<Ad, SubmittedValue> values = root.join(Ad_.values);

ListJoin<Ad, SubmittedValue> values = root.joinList(Ad_.values);

通过将isspecial作为如下参数值,可以使您的规范更加动态

public static Specification<Ad> adSpecial(Long userId, Boolean isSpecial) {
    return (root, query, criteriaBuilder) -> {
        ListJoin<Ad, SubmittedValue> values = root.joinList("values");

        List<Predicate> conditions = new ArrayList<>();
        conditions.add(criteriaBuilder.equal(values.get("configuration").get("isSpecial"), isSpecial));
        conditions.add(criteriaBuilder.equal(root.get("user").get("id"), userId));

        return criteriaBuilder.and(conditions.toArray(new Predicate[0]));
    };
}

相关问题