Consultar jpql com o createQuery do EntityManager retornando erro

9 respostas Resolvido
oraclejavasql
R

Estou tentando realizar a consulta abaixo, porém estou recebendo erro. Eu já tentei obter o ano de várias maneiras, mas nenhuma da certo, alguém poderia me ajudar?

Tentativas: to_char(…, ‘yyyy’)
to_date(…, ‘yyyy’)
Todas não são reconhecidas pelo entityManager.

public String findTeste() {
        String classe = MetaBaseAtivos.class.getName().toString();
        String nomePuro = classe.substring(classe.lastIndexOf(".") + 1, classe.length());
        StringBuilder sb = new StringBuilder();
        
        sb.append("select year(").append(nomePuro.toLowerCase()).append(".dataMeta) from ").append(nomePuro).append(" ").append(nomePuro.toLowerCase()).append(" ");
        sb.append(" where 1 = 1 and ").append(nomePuro.toLowerCase()).append(".codigo = 303231");
        
        javax.persistence.Query q = getEntityManager().createQuery(sb.toString());
        
        return (String) q.getSingleResult();
        
    }
Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.JPQLException

Exception Description: Syntax error parsing [select year(metabaseativos.dataMeta) from MetaBaseAtivos metabaseativos  where 1 = 1 and metabaseativos.codigo = 303231].

[10, 11] The SELECT clause has year and (metabaseativos.dataMeta) that are not separated by a comma.

at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildException(HermesParser.java:155)

at org.eclipse.persistence.internal.jpa.jpql.HermesParser.validate(HermesParser.java:334)

at org.eclipse.persistence.internal.jpa.jpql.HermesParser.populateQueryImp(HermesParser.java:278)

at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildQuery(HermesParser.java:163)

at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:140)

at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:116)

at org.eclipse.persistence.internal.jpa.EJBQueryImpl.(EJBQueryImpl.java:102)

at org.eclipse.persistence.internal.jpa.EJBQueryImpl.(EJBQueryImpl.java:86)

at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1741)

 88 more

9 Respostas

J

Para SQL use o método createNativeQuery.

R

Mas eu tenho várias outras consultas que seguem esse padrão, então não posso fugir disso.

Não existiria uma forma de se fazer isso como estou usando?

J

Você postou falando em “Consultar SQL”. Para SQL o método é createNativeQuery. createQuery é para hql/jpql.

R

Arrumei o tópico, desculpe pelo erro.

R

up

M

As funções acima só funcionam com query nativas.

Porque você não utiliza query nativa? Não há problema algum…
É como dizer: “Não vou usar LinkedList porque minha aplicação usa ArrayList”.

select extract (year from metabaseativos.datameta) from metabaseativos
F

Mais ou menos. Se você precisar fazer uma migração de banco no futuro irá ter que transcrever tudo que está em query’s nativas para o análogo no novo banco. Eu optaria por escrever em hql também, mas ressalto que há algum trabalho a ser feito em termos de performance, quem já trabalhou com hibernate sabe do que estou falando.

De uma olhada no manual do hql:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-expressions

Acredito que você encontre como escrever a query corretamente.

M

Essa query é bem simples até, apenas um extract.
Eu sei que a query funciona no MySQL, PostgreSQL e Oracle

Se por acaso ele não conseguir com jpql, terá que optar pela nativa mesmo e é bem rápida por sinal

Quando se trata de datas eu sempre usei nativeQuery, o problema seria a troca de banco mesmo, caso a empresa tivesse um banco X e esse banco o extract nao funcionaria, ai teria que ser jpql.

Eu sei que da pra fazer com Criteria a extração do ano, mas eu nunca fiz…

R
Solucao aceita

O problema é que a query que eu coloquei era apenas um teste que eu estava fazendo,

A que eu iria utilizar mesmo era mais trabalhosa, mas eu consegui fazer através do extract mesmo e com a createQuery.

StringBuilder sb = new StringBuilder();
        sb.append("select (SUM(").append(nomePuro.toLowerCase()).append(".valorImob)-SUM(").append(nomePuro.toLowerCase()).append(".valorObrig)) from ").append(nomePuro).append(" ").append(nomePuro.toLowerCase()).append(" ");
        sb.append(" where 1 = 1 and ").append(nomePuro.toLowerCase()).append(".ativo = 1");

        if(dataMeta != null) { 
            sb.append(" and extract(month from ").append(nomePuro.toLowerCase()).append(".data) = extract(month from :valorDataMeta)");
            sb.append(" and extract(year from ").append(nomePuro.toLowerCase()).append(".data) = extract(year from :valorDataMeta)");
        }
        if (area != null) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".cr.idArea.codigo = :areaID ");
        }
        
        javax.persistence.Query q = getEntityManager().createQuery(sb.toString());

        if (area != null) {
            q.setParameter("areaID", area.getCodigo());
        }
        
        if(dataMeta != null) {
            q.setParameter("valorDataMeta", dataMeta);
        }

        return (BigDecimal) q.getSingleResult();
Criado 23 de março de 2018
Ultima resposta 26 de mar. de 2018
Respostas 9
Participantes 4