Как создать отдельный запрос в HQL? - PullRequest
96 голосов
/ 05 ноября 2008

Есть ли способ создать отдельный запрос в HQL. Либо с помощью «отличного» ключевого слова, либо с помощью другого метода. Я не уверен, является ли отличное значение допустимым ключом для HQL, но я ищу HQL-эквивалент ключевого слова SQL «другое».

Ответы [ 9 ]

121 голосов
/ 05 ноября 2008

Вот фрагмент hql, который мы используем. (Имена были изменены для защиты личности)

String queryString = "select distinct f from Foo f inner join foo.bars as b" +
                " where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
        return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});
52 голосов
/ 24 ноября 2008

Стоит отметить, что ключевое слово distinct в HQL не отображается напрямую в ключевое слово distinct в SQL.

Если вы используете ключевое слово distinct в HQL, то иногда Hibernate будет использовать ключевое слово SQL distinct, но в некоторых ситуациях он будет использовать преобразователь результатов для получения различных результатов. Например, когда вы используете внешнее соединение, как это:

select distinct o from Order o left join fetch o.lineItems

В этом случае невозможно отфильтровать дубликаты на уровне SQL, поэтому Hibernate использует ResultTransformer для фильтрации дубликатов после SQL-запроса был выполнен.

15 голосов
/ 20 мая 2011

сделай что-нибудь подобное в следующий раз

 Criteria crit = (Criteria) session.
                  createCriteria(SomeClass.class).
                  setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 List claz = crit.list();
9 голосов
/ 14 августа 2014

Вы также можете использовать Criteria.DISTINCT_ROOT_ENTITY с Hibernate HQL-запросом.

Пример:

Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
4 голосов
/ 28 мая 2009

У меня были некоторые проблемы с преобразователями результатов в сочетании с HQL-запросами. Когда я попробовал

final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);

это не сработало. Мне пришлось преобразовать вручную, как это:

final List found = trans.transformList(qry.list());

С Criteria API преобразователи работали просто отлично.

3 голосов
/ 03 ноября 2014

Мой основной запрос выглядел так в модели:

@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd", 
    query = "select distinct i from CentralFinancialAgencyAccountCd i")

И я все еще не получал то, что считал «отличными» результатами. Они были просто различны, основываясь на комбинации первичных ключей в таблице.

Итак, в DaoImpl я добавил изменение в одну строку и в итоге получил «отчетливый» возврат, который хотел. Например, вместо того, чтобы видеть 00 четыре раза, я теперь просто вижу это один раз. Вот код, который я добавил к DaoImpl:

@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {

    Session session = (Session) entityManager.getDelegate();
    org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
    q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
    List<CacheModelBase> codes;
    codes = q.list();
    return codes;       
}

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

2 голосов
/ 12 мая 2015

Предположим, у вас есть Клиентский объект, сопоставленный с таблицей CUSTOMER_INFORMATION, и вы хотите получить список различных имен FirstName клиента. Вы можете использовать ниже фрагмент, чтобы получить то же самое.

Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();

Надеюсь, это поможет. Так что здесь мы используем group by вместо отдельного ключевого слова.

Также ранее мне было трудно использовать отличное ключевое слово, когда я хочу применить его к нескольким столбцам. Например, я хочу получить список различных firstName, lastName, а затем group by будет просто работать. У меня были трудности с использованием различных в этом случае.

1 голос
/ 21 августа 2018

Вы можете использовать отдельное ключевое слово в построителе критериев, как это.

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));

И создайте конструктор поля в классе вашей модели.

0 голосов
/ 22 февраля 2013

У меня есть ответ на Hibernate Query Language для использования различных полей. Вы можете использовать * SELECT DISTINCT (TO_CITY) FROM FLIGHT_ROUTE *. Если вы используете SQL запрос, он возвращает String List. Вы не можете использовать это возвращаемое значение по классу сущностей. Таким образом, ответом для решения этого типа проблемы является использование HQL с SQL .

FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);

С SQL оператор запроса получил DISTINCT ROUTE_ID и введен в виде списка. И запрос IN фильтрует отличную TO_CITY от IN (Список).

Тип возвращаемого значения: тип Entity Bean. Так что вы можете сделать это в AJAX, например Автозаполнение .

Все может быть в порядке

...