Построение запроса с использованием NOT EXISTS в jpa-критериях api

У меня есть две таблицы с именем table1, table2.Both, таблицы имеют одинаковое количество полей. Между этими двумя таблицами нет никакой связи. Моим требованием я хочу, чтобы все записи в таблице1 отсутствовали в таблице2. Поэтому я написал запрос с использованием API критериев. Но это не дает правильного результата. Поскольку я новичок в этом JPA и API критериев, может ли кто-нибудь указать мне, где я делаю неправильно. Ниже код, который я использую для этого.

CriteriaBuilder cb = mediationEntityManager.getCriteriaBuilder();
CriteriaQuery<Table1>  cq = cb.createQuery(Table1.class);
Root<Table1> table1 = cq.from(Table1.class);
cq.select(table1)

Subquery<Table2> subquery =  cq.subquery(Table2.class)
Root table2 = subquery.from(Table2.class)
subquery.select(table2)
cq.where(cb.not(cb.exists(subquery)))
TypedQuery<Table1> typedQuery = mediationEntityManager.createQuery(cq); 
List<Table1> resultList = typedQuery.getResultList();

Запрос MySQL:

SELECT table1 
FROM   table1 table1 
WHERE  NOT EXISTS (SELECT table2 
                   FROM   table2 table2 
                   WHERE  table2.name = table1.name 
                          AND table2.education = table1.education 
                          AND table2.age = table1.age) 
       AND table1.name = 'san' 
       AND table1.age = '10'; 

Мне нужен запрос API критериев JPA для вышеупомянутого MySQL-запроса.

Ответ 1

Вы можете попробовать приведенный ниже код с Criteria API. Я не пробовал, но вы можете изменить код соответствующим образом.

CriteriaBuilder cb = mediationEntityManager.getCriteriaBuilder();  
CriteriaQuery<Table1> query = cb.createQuery(Table1.class); 
Root<Table1> table1 =  query.from(Table1.class); 
query.select(table1);
//--  
Subquery<Table2> subquery = query.subquery(Table2.class); 
Root<Table2> table2 = subquery.from(Table2.class);  
subquery.select(table2);  
//--
List<Predicate> subQueryPredicates = new ArrayList<Predicate>(); 
subQueryPredicates.add(cb.equal(table1.get(Table1_.name), table2.get(Table2_.name)));
subQueryPredicates.add(cb.equal(table1.get(Table1_.age), table2.get(Table2_.age)));
subQueryPredicates.add(cb.equal(table1.get(Table1_.education), table2.get(Table2_.education)));
subquery.where(subQueryPredicates.toArray(new Predicate[]{})); 
//--
List<Predicate> mainQueryPredicates = new ArrayList<Predicate>(); 
mainQueryPredicates.add(cb.equal(table1.get(Table1_.name), "san");
mainQueryPredicates.add(cb.equal(table1.get(Table1_.age), "10");
mainQueryPredicates.add(cb.not(cb.exists(subquery))); 
//--
query.where(mainQueryPredicates.toArray(new Predicate[]{})); 
TypedQuery<Table1> typedQuery =  mediationEntityManager.createQuery(query); 
List<Table1> resultList = typedQuery.getResultList();

Кроме того, вы можете попробовать ниже JPQL-запрос, который легче понять, изменить и отладки.

SELECT t1 
FROM   table1 t1, 
       table2 t2 
WHERE  t1.name = 'san' 
       AND t1.age = '10' 
       AND (t2.name <> t1.name 
             AND t2.education <> t1.education 
             AND t2.age <> t1.age);