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".

Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top