Я использую спецификацию загрузки Spring и пытаюсь выполнить запрос, который выглядит так:

SELECT DISTINCT
    p.name
FROM
    partner p
        INNER JOIN
    detail d ON p.detail_id = d.id
        INNER JOIN
    account a ON d.account_id = a.id
        OR d.crm_id = a.top_parent
        OR d.crm_id = a.global_partner

Я использовал код

  Join<Partner, Detail> details = root.join("detail");
  Join<Detail, Account> account = details.join("account");
  Predicate global = cb.equal(details.get("crm_id "), account.get("top_parent"));
  Predicate top = cb.equal(details.get("crm_id "), account.get("global_partner"));
  account.on(cb.or(global, top));

Однако он создает запрос

SELECT DISTINCT
    p.name
FROM
    partner p
        INNER JOIN
    detail d ON p.detail_id = d.id
        INNER JOIN
    account a ON d.account_id = a.id
        AND (d.crm_id = a.top_parent
        OR d.crm_id = a.global_partner)

Обратите внимание на оператор И в запросе ... Мне нужно заменить его на оператор ИЛИ

Другой вариант использования, с которым я борюсь

@Entity
public class Detail {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  
  @OneToMany(mappedBy = "detail", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  private Set<Skill> skills;
}

Я пытаюсь сгенерировать запрос ниже, используя спецификации

order by (select count(s.detail_id) from skill s where detail.id = s.detail_id AND s.category is not null) desc

Я использовал код ниже

cq.orderBy(cb.desc(cb.size(details.get("skills"))));

Но запрос, который он генерирует,

order by (select count(s.detail_id) from skill s where detail.id = s.detail_id) desc

Обратите внимание, что я не могу добавить дополнительное И к предложению order by

0
Tapan 19 Май 2021 в 16:45

1 ответ

Лучший ответ

Я считаю, что вы не можете изменить это И. не могли бы вы изменить запрос следующим образом

SELECT DISTINCT p.name
FROM partner p INNER JOIN detail d ON p.detail_id = d.id, account a
where d.account_id = a.id
OR d.crm_id = a.top_parent
OR d.crm_id = a.global_partner

И критерии jpa, аналогичные

    Join<Partner, Detail> details = root.join("detail");
    Root<Account> account = criteria.from(Account.class);
    Predicate global = cb.equal(details.get("crm_id"), account.get("top_parent"));
    Predicate top = cb.equal(details.get("crm_id"), account.get("global_partner"));
    Predicate byId = cb.equal(details.get("account").get("id"), account.get("id"));
    Predicate or = cb.or(global, top, byId);
    criteria.where(or);
1
tremendous7 20 Май 2021 в 00:23