Критерии JPA ИЛИ условие для связанного объекта с навигацией по пути - PullRequest
0 голосов
/ 28 сентября 2018

У меня следующая структура сущностей

public class Application {
    @JoinColumn(name = "account_id")
    @ManyToOne
    private Account account;

    @JoinColumn(name = "involved_account_id")
    @ManyToOne
    private Account involvedAccount;
}

public class Account {
    private string id;
    private string name;
}

Я хочу получить все приложения, в которых account имя или involvedAccount имя соответствует имени учетной записи.

CriteriaQuery<Application> query = cb.createQuery(Application.class);
Root<Application> root = query.from(Application.class);

Predicate conditions = cb.conjunction();

conditions = cb.and(conditions, cb.or(
    cb.like(
        cb.upper(root.get("account").get("name")), 
        accountName.toUpperCase()
    ), cb.like(
        cb.upper(root.get("involvedAccount").get("name")), 
        accountName.toUpperCase())
    )
);

query.where(conditions);
query.select(root);

Но вышеприведенное приводит к следующему условию, в котором используется and для первичных ключей, а не or

where applicati0_.account_id=account1_.id
    and applicati0_.involved_account_id=account2_.id
    and 1=1
    and (
        upper(account1_.name) like ?
        or upper(account2_.id) like ?
    )

. Здесь условие не выполняется, так как выражение applicati0_.account_id=account1_.id and applicati0_.involved_account_id=account2_.id использует and вместо or

1 Ответ

0 голосов
/ 28 сентября 2018

Используйте join, как предлагается в комментариях.

Сейчас я не могу проверить, но что-то вроде этого должно работать:

CriteriaQuery<Application> query = cb.createQuery(Application.class);
Root<Application> root = query.from(Application.class);
Join<Application, Account> account = root.join("account");
Join<Application, Account> involvedAccount = root.join("involvedAccount");

Predicate conditions = cb.conjunction();

conditions = cb.and(conditions, cb.or(
    cb.like(
        cb.upper(account.get("name")), 
        accountName.toUpperCase()
    ), cb.like(
        cb.upper(involvedAccount.get("name")), 
        accountName.toUpperCase())
    )
);

query.where(conditions);
query.select(root);
...