У меня проблемы с предикатом в JPA в унаследованном коде - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть некоторый унаследованный код, который использует JPA и должен вернуть список всех процессов, которые включают все перечисленные химикаты - операция AND.Тем не менее, список всегда пуст.Код, который возвращает процессы, в которых есть какие-либо из перечисленных химических веществ (ИЛИ), выглядит нормально.Версия JDK составляет 1.7.Hibernate 5.0.2

Я пытался просмотреть Javadocs, учебники по JPA и hibernate и т. Д. Но ни один из них не дает мне хорошего представления о классе Predicate.

final CriteriaBuilder cb = getCriteriaBuilder();
final CriteriaQuery<Process> cq = cb.createQuery(Process.class);
final Root<Constituent> constituentRoot  = cq.from(Constituent.class);
List<Predicate> clist - new ArrayList<Predicate>();
//chemical_id_list is a List of type Integer = List<Integer> passed to method.
//It contains all of the ids of the chemicals of interest.
for (Integer id: chemical_id_list) {
  clist.add(cb.equal(constituentRoot.get(Constituent_.chemical), id));
}

//Code in common with the OR operation, which works..

Мне кажется, что cb.equal часть этого кода неверна.Constituent_.chemical - это атрибут класса Constituent, а не целое число, которым является параметр «id».Как химический объект может быть "равен" целому числу?Или я что-то совершенно неправильно понимаю?Спасибо за ваше время.

Вот то, что находится в Учредительном классе:

public class Constituent implements Serializable{

private int constituentId;
private String chemicalNotes;
private String  labelText;
private String quantity;
private int sort;
private Chemical chemical;
private Phase phase;
private Role role;
private Step step;

//getters and setters
}

Вот что находится в Химическом классе:

public class Chemical
{
 private int chemicalId;
 private String boilingPoint;
 private String canonicalFormula;
 private String meltingPoint;
 private String name;
 private String notes;
//getters and setters
}

Вот чтонаходится в классе Process, хотя я не показываю его использование в коде здесь:

public class Process
{
   private int processId;
   private String name;
   private String notes;
   private List<Step> steps;
//Getters and setters not shown.
}

1 Ответ

0 голосов
/ 06 февраля 2019

Проблема в этом запросе состоит в том, что вы присоединяетесь к chemical только один раз.Благодаря этому вы проверяете, что id из этого 1 chemical равно всем Integer в вашем List.Итак, как только вы List содержат более одного Integer, набор результатов будет пустым.

Вам потребуется отдельное объединение для каждого идентификатора химического вещества, которое вы хотите проверить.

Этот запрос должен вернуть все Constituent, которые имеют все Chemical, идентифицированные chemical_id_list

final CriteriaBuilder cb = getCriteriaBuilder();
final CriteriaQuery<Process> cq = cb.createQuery(Process.class);
final Root<Constituent> constituentRoot  = cq.from(Constituent.class);
List<Predicate> clist - new ArrayList<Predicate>();
//chemical_id_list is a List of type Integer = List<Integer> passed to method.
//It contains all of the ids of the chemicals of interest.
for (Integer id: chemical_id_list) {
  Join<Constituent, Chemical> chemical = root.join(Constituent_.chemical);
  clist.add(cb.equal(chemical.get(Chemical_.id), id));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...