2011-07-18 2 views
7

Я не знаю, как сделать запрос критериев JAP в конечном итоге с булевым выходом.Как правильно определить, верна ли ложная или ложная фраза «Существование» в заявлении о критериях запроса JPA?

Цель состоит в том, чтобы иметь критерии запроса, который выглядит следующим образом при визуализации на Oracle:

select 1 from dual where exists (...); 

where exists (...) часть я сделал с подзапроса, я борюсь с внешним запросом.

И практическое использование этого заключается в том, чтобы определить, был ли возвращен этот подзапрос в оговорке existstrue или false.

Это то, что я получил:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); 

CriteriaQuery<Object> query = criteriaBuilder.createQuery(); 
query.from(Boolean.class); 
query.select(criteriaBuilder.literal(true)); 

Subquery<Location> subquery = query.subquery(Location.class); 
Root<Location> subRootEntity = subquery.from(Location.class); 
subquery.select(subRootEntity); 

Path<?> attributePath = subRootEntity.get("State"); 
Predicate predicate = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("TX")); 
subquery.where(predicate); 
query.where(criteriaBuilder.exists(subquery)); 

TypedQuery<Object> typedQuery = em.createQuery(query); 

Но последняя строка не может говоря булева не является сущностью. Я думаю, что моя проблема не известна, как выражать «из» части запроса, поскольку результатом будет 1 или 0, true или false, а не сущность.

Я знаю, что я мог бы получить любую сущность, а затем проверить, имеет ли список результатов размер 1, но я пытаюсь узнать, как получить логический результат напрямую, чтобы избежать ненужной задачи по извлечению этих столбцов, а также узнать как это сделать.

Возможно ли это вообще?

Спасибо! Eduardo

+2

Нет, вы не можете напрямую сделать это, но общий путь для проверки подсчета результирующего набора, если счетчик т.е. больше нуля, то верно еще ложь. – Shahzeb

ответ

6

Вы могли бы сделать выбор для одного свойства (например, идентификатор) и установить результаты макс вернулся к 1, так что вы убедитесь, что DB не делать больше работы, чем это необходимо (например, подсчет всех экземпляров). Тогда ваш список результатов будет либо пустым (exists = false), либо иметь один элемент (exists = true).

+0

Это то, что я искал, способ сделать это без необходимости работать с СУБД более чем необходимо. Благодаря!! –

0

Я думаю, что проблема заключается в вопросе query.from (Boolean.class). Он пытается создать запрос «select object from boolean». Если вы хотите, логическое значение в качестве возвращаемого типа необходимо использовать

CriteriaQuery<Boolean> query = criteriaBuilder.createQuery(Boolean.class) 

Тогда запрос из любой существующей таблицы сущностей, чтобы создать правильный запрос (возможно, со стола подзапроса). Я не думаю, что создавать из двойных работ, за исключением случаев, когда вам удалось сопоставить двойную таблицу.

-2

Есть ли причина, по которой вся логика должна быть в JPA? Если нет, почему бы не использовать SELECT COUNT, а затем условное, чтобы установить логическое значение?

Boolean exists = false; 
int count = selectCountQuery(); 
if (count > 0) { 
    exists = true; 
} 
10

Да, это возможно. Предполагая, что у вас есть объект, соответствующий вашей таблице dual, вы захотите использовать этот класс сущностей в CriteriaQuery#from.

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); 

CriteriaQuery<Boolean> query = criteriaBuilder.createQuery(Boolean.class); 
query.from(dual.class); 
query.select(criteriaBuilder.literal(true)); 

Subquery<Location> subquery = query.subquery(Location.class); 
Root<Location> subRootEntity = subquery.from(Location.class); 
subquery.select(subRootEntity); 

Path<?> attributePath = subRootEntity.get("State"); 
Predicate predicate = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("TX")); 
subquery.where(predicate); 
query.where(criteriaBuilder.exists(subquery)); 

TypedQuery<Boolean> typedQuery = em.createQuery(query); 
2

Я знаю, что это старая проблема, но для тех, кто еще ищу: Как о попытке использовать JPA @Query аннотации Spring, и выберите случай запрос (в зависимости от реализации БД) с помощью метода, который возвращает логическое значение , Например (MySQL):

@Query("SELECT CASE WHEN COUNT(l) > 0 THEN TRUE ELSE FALSE END FROM Location l WHERE l.state=?1") 
boolean locationForStateExists(String state); 

Иногда только с помощью строки запроса в @Query может быть спасатель, когда названный JPA или методы строитель запросов не совсем то, что вы хотите.

+0

Это зависит от 'count()', что является основной проблемой. Hibernate не поддерживает ключевое слово 'exist', кроме внутри предложения' where', которое не выполняет то, что запрашивает OP. Выбор 'count' может быть чрезвычайно медленным (в зависимости от сложности предложения' where', наличия индексов и т. Д.), В то время как предложение 'exist' будет быстро сбой при первом вхождении. Это позор JPA/Hibernate не поддерживает эту тривиальную оптимизацию. –

1

Hibernate 5 не работает:

Subquery<Integer> subquery = query.subquery(Integer.class); 
Root<Location> subRootEntity = subquery.from(Location.class); 
subquery.select(criteriaBuilder.literal(1)); 

Path<?> attributePath = subRootEntity.get("State"); 
Predicate predicate = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("TX")); 
subquery.where(predicate); 
query.where(criteriaBuilder.exists(subquery)); 
+0

Благодарим за обновление! –

 Смежные вопросы

  • Нет связанных вопросов^_^