Como você cria uma consulta distinta em HQL
Pergunta
Existe uma maneira de criar uma consulta distinta em HQL. Ou usando a palavra-chave "distinto" ou algum outro método. Não estou certo se distinta é uma keywork válido para HQL, mas eu estou procurando o equivalente HQL da palavra-chave SQL "distinta".
Solução
Aqui está um trecho de hql que usamos. (Os nomes foram alterados para identidades Proteger)
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});
Outras dicas
É importante notar que a palavra-chave distinct
em HQL não mapeia diretamente para a palavra-chave distinct
em SQL.
Se você usar a palavra-chave distinct
em HQL, então às vezes o Hibernate irá usar a palavra-chave SQL distinct
, mas em algumas situações ele vai usar um transformador de resultado para produzir resultados distintos. Por exemplo, quando você estiver usando uma junção externa como esta:
select distinct o from Order o left join fetch o.lineItems
Não é possível filtrar as duplicatas no nível SQL neste caso, de modo Hibernate usa uma ResultTransformer
de duplicatas filtro depois a consulta SQL foi executada.
fazer algo assim na próxima vez
Criteria crit = (Criteria) session.
createCriteria(SomeClass.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List claz = crit.list();
Você também pode usar Criteria.DISTINCT_ROOT_ENTITY
com consulta Hibernate HQL também.
Exemplo:
Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
Eu tive alguns problemas com transformadores resultado combinado com consultas HQL. Quando eu tentei
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
não funcionou. Eu tive que transformar manualmente assim:
final List found = trans.transformList(qry.list());
Com transformadores API Critérios funcionou muito bem.
A minha consulta principal era assim no modelo:
@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd",
query = "select distinct i from CentralFinancialAgencyAccountCd i")
E eu ainda não estava recebendo o que eu considerava resultados "distintas". Eles eram apenas distintas com base em uma combinação de chave primária na tabela.
Assim, no DaoImpl
eu adicionei uma mudança de uma linha e acabou recebendo o "distinto" voltar eu queria. Um exemplo seria em vez de ver 00 quatro vezes eu agora só vê-lo uma vez. Aqui está o código que adicionado ao 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;
}
Espero que isso ajudou! Mais uma vez, isso pode funcionar apenas se você está seguindo práticas de codificação que implementam o serviço, dao, e tipo de modelo de projeto.
Suponha que você tenha um Cliente Entidade mapeado para a tabela CUSTOMER_INFORMATION e que pretende obter a lista de firstName distinta do cliente. Você pode usar o abaixo trecho para obter o mesmo.
Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();
Espero que ajude. Então, aqui estamos usando grupo, em vez de usar palavra-chave distinta.
Além disso anteriormente eu achei difícil de usar palavra-chave distinta quando quero aplicá-la a várias colunas. Por exemplo, eu quero da lista get de firstName distinta, lastName então grupo por simplesmente trabalho. Eu tive dificuldade em usar distinta neste caso.
Você pode-lhe a palavra-chave distinta em você critérios construtor assim.
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));
E criar o construtor de campo em sua classe de modelo.
Eu tenho uma resposta para Hibernate Query Language usar campos distintos. Você pode usar * SELECT DISTINCT (TO_CITY) FROM FLIGHT_ROUTE *. Se você usar SQL consulta, ele voltar lista de textos. Você não pode usá-lo valor retornar pela Entidade de Classe. Portanto, a resposta para resolver esse tipo de problema é o uso HQL com SQL .
FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);
De SQL instrução de consulta ficou DISTINCT route_id e de entrada como uma lista. E na consulta filtrar o TO_CITY distinta da IN (Lista).
O tipo de retorno é do tipo Entity Bean. Assim você pode-lo em AJAX como AutoComplement .
podem ser todos OK