oi pessoal estou trabalhando com consultas em JPA
numa consulta normal @NamedQuery(name = "Area.findByDescricao", query = "SELECT a FROM Area a WHERE a.descricao = :descricao")
funciona
em SQL essa consulta funciona numa boa
select * from area where descricao ~* 'o'
mas quando eu coloco
não funciona e da esse erro:
Erro durante a implantação: Exception while preparing the app : Exception [EclipseLink-8025] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing the query [Area.findByDescricao: select * from area where descricao ~* descricao], line 1, column 8: unexpected token [*].
Internal Exception: NoViableAltException(93@[330:16: ( DISTINCT )?]). Consulte o server.log para obter informações detalhadas.
/home/jaisson/Área de Trabalho/pesquisaDocumento/nbproject/build-impl.xml:726: O módulo não foi implementado.
Verifique o registro do servidor para mais detalhes.
FALHA NA CONSTRUÇÃO (tempo total: 1 segundo)
pois é no banco a consulta funciona, por que no JPA não, tem como eu fazer pro JAP entender que isso funciona, ou tem outro modo de fazer
se o ~* (que eu não faço idéia do que é hehe) não faz parte da sintaxe do JPQL, talvez por ser específico de algum banco, creio que não vá funcionar
rafaduka
Algumas abreviações, são particular para cada banco.
Para JPA neste caso poderia-se utilizar LIKE
[google]LIKE JPA[/google]
jaissonduarte
ai que coisa, a gente fala pela metade
bom o ~* eu uso no Postgres (não testei em outros banco)
com esse operador ele busca tudo que for parecido com o dado informado
exemplo, tenho os dados:
Informática,
Informatica,
informática,
informatica,
oi
note que tem diferenças nas palavras essas 4 palavras para nós é uma só mas para o banco são 4, como todos sabem casesentive (acho que é assim que escreve)
ai se informar o carácter “e”, ele (banco) não vai trazer nada, mas se colocar “a”, ele vai trazer tudo, menos o oi,
legal né
Hebert_Coelho
Então você terá que utilizar NativeQuery. Com isso você consegue utilizar a Query específica para o banco de dados em questão.
jaissonduarte
finalmente uma luz no fim do túnel
como eu faço com NativeQuery tem algum exemplo?
Hebert_Coelho
jaissonduarte:
finalmente uma luz no fim do túnel
como eu faço com NativeQuery tem algum exemplo?
@Entity@Table(name="area")@XmlRootElement@NamedNativeQuery(name="findByDescricao",query="SELECT * a FROM Area a WHERE a.descricao ~* descricao",resultClass=Area.class)/*@NamedQueries({ @NamedQuery(name = "Area.findAll", query = "SELECT a FROM Area a"), @NamedQuery(name = "Area.findByCodigo", query = "SELECT a FROM Area a WHERE a.codigo = :codigo"), /*@NamedQuery(name = "Area.findByDescricao", query = "select * from area where descricao ~* descricao")})*/publicclassAreaimplementsSerializable{privatestaticfinallongserialVersionUID=1L;//public static final String pesquisarpublicstaticfinalStringpesquisarDescricao="findByDescricao";@Id@Basic(optional=false)@NotNull@Column(name="codigo")privateIntegercodigo;@Basic(optional=false)@NotNull@Size(min=1,max=30)@Column(name="descricao")privateStringdescricao;
Informações: erro
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near "findByDescricao"
Error Code: 0
Call: findByDescricao
Query: DataReadQuery(sql="findByDescricao")
o que vocês acham que pode ser?
Hebert_Coelho
Novamente, você tem que usar NativeQuery e não NamedQuery. NamedQuery utiliza JPQL e não tem suporte ao ~*. NativeQuery você consegue utilizar sintax do banco mesmo.
jaissonduarte
jakefrog:
Novamente, você tem que usar NativeQuery e não NamedQuery. NamedQuery utiliza JPQL e não tem suporte ao ~*. NativeQuery você consegue utilizar sintax do banco mesmo.
?????
mas estou usando o NativeQuery, até comentei minhas NamedQuery
no site o cara fez isso:
@NamedNativeQuery(name="nativeTopicByDate",query="SELECT topic.TITLE, topic.CREATION_DATE FROM TOPIC topic "+"WHERE topic.MODIFED_DATE=?",resultClass=Topic.class)
e eu:
@Entity@Table(name="area")@NamedNativeQuery(name="findByDescricao",query="SELECT * a FROM Area a WHERE a.descricao ~* descricao",resultClass=Area.class)publicclassAreaimplementsSerializable{publicstaticfinalStringpesquisarDescricao="findByDescricao";.....
e o erro:
Informações: erro
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near "findByDescricao"
Error Code: 0
Call: findByDescricao
Query: DataReadQuery(sql="findByDescricao")
que coisa não? :D
Hebert_Coelho
Ops! Não vi direito. Mals! :oops:
Olha isso: SELECT * a FROM Area a WHERE a.descricao ~* descricao
troque * a por * apenas. :lol:
Outra coisa, troque de descricao para :descricao . :lol:
jaissonduarte
jakefrog:
troque * a por * apenas. :lol:
Outra coisa, troque de descricao para :descricao . :lol:
será que você quis dizer assim?
deu esse erro:
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near "findByDescricao"
Error Code: 0
Call: findByDescricao
Query: DataReadQuery(sql=“findByDescricao”)
Hebert_Coelho
Se você rodar SELECT * FROM Area WHERE descricao ~* :descricao direto no postgres ele funciona? Trocando o :descricao por algum valor válido?
jaissonduarte
roda que é uma beleza,
daqui a pouco vou deixar meu sistema com usabilidade -5
Hebert_Coelho
Tenta assim: em.createNativeQuery(“select * from area where descricao ~* :descricao”, Area.class);
Teoricamente tá tudo certo mano. O.o
jaissonduarte
Cara da uma olhada no meu código e me diga o que tem de errado
packagedao;importjava.util.List;importjavax.ejb.Stateless;importjavax.persistence.EntityManager;importjavax.persistence.PersistenceContext;importjavax.persistence.Query;importmodelo.Area;@StatelesspublicclassAreaDAO{@PersistenceContext(name="pesquisaDocumentoPU")privateEntityManagerem;privateAreaarea;publicList<Area>pesquisar(Stringdescricao){List<Area>resultado=null;try{Queryconsulta=em.createNativeQuery("select * from area where descricao ~* :descricao",Area.class);consulta.setParameter("descricao",descricao);resultado=consulta.getResultList();}catch(Exceptione){System.out.println("não deu hehehes: "+e.getMessage());}returnresultado;}}
por que esta dando esse erro:
Informações: não deu hehehes:
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near ":"
Error Code: 0
Call: select * from area where descricao ~* :descricao
Query: ReadAllQuery(referenceClass=Area sql="select * from area where descricao ~* :descricao")
quando retiro o ":"
Informações: não deu hehehes:
Exception Description: The primary key read from the row [ArrayRecord(
=> 3
=> Informática)] during the execution of the query was detected to be null. Primary keys must not contain null.
Query: ReadAllQuery(referenceClass=Area sql="select * from area where descricao ~* descricao")
tem outra forma de fazer esse consulta?
Hebert_Coelho
Faz um teste: select * from area where descricao = :descricao
e passa uma descrição que exista no banco.
Caso funcione, pode ser o driver do postgres que não está reconhecendo o comando.
jaissonduarte
quando coloco o NativeQuery da esse erro:
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near "Descricao"
Error Code: 0
Call: Descricao
Query: DataReadQuery(sql=“Descricao”)
com o NamedQuery ele funciona normal
Hebert_Coelho
Pq seu Descricao está com D maiúsculo?
Vc colocou como eu passei?
jaissonduarte
o descricao com D maisculo é o nome da consulta da uma olhada:
@NamedNativeQuery(name="Descricao",query="SELECT * FROM Area WHERE descricao ~* descricao")
@NamedQueries({
@NamedQuery(name = "Area.findAll", query = "SELECT a FROM Area a"),
@NamedQuery(name = "Area.findByCodigo", query = "SELECT a FROM Area a WHERE a.codigo = :codigo"),
@NamedQuery(name = "byDescricao", query = "SELECT a FROM Area a WHERE a.descricao = :descricao")})
public class Area implements Serializable {
private static final long serialVersionUID = 1L;
public static final String pesquisarDescricao="byDescricao";
public static final String pesquisar="Descricao";
Não cara, lah ainda continua com o ~* @NamedNativeQuery(name="Descricao",query="SELECT * FROM Area WHERE descricao ~* descricao")Faça assim: em.createNativeQuery(“select * from area where descricao = :descricao”, Area.class);
ricardobocchi
Cara, tenta executar essa query fora de uma NamedQuery, só pra testar… tipo
Query query = session.createSQLQuery("SELECT * FROM Area WHERE descricao ~* :descricao");
query.setParameter("descricao", "o");
List result = query.list();
Se não der certo, talves o driver não suporte… mas acho dificil que seja isso… De qualquer maneira, esse comando não é equivalente a isso?
Query query = session.createSQLQuery("SELECT * FROM Area WHERE UPPER(descricao) like :descricao");
query.setParameter("descricao", "%o%".toUpperCase());
List result = query.list();
Se te servir, nem precisa ser query nativa… pode ser HQL mesmo
jaissonduarte
e ai meu
cara da onde tu tirou esse session?
ricardobocchi
tu deve ter uma sessão em algum lugar, ou um entity manager, onde tu pode executar uma sql, hql ou criteria, não?
testei sim
e deu esse erro:
Exception Description: The primary key read from the row [ArrayRecord(
=> 3
=> Informática)] during the execution of the query was detected to be null. Primary keys must not contain null.
Query: ReadAllQuery(referenceClass=Area sql=“select * from area where descricao = descricao”)
vai entender nem tenho esse dado?
mas cara estava fazendo uma gambiarras medonhas e acho que meu problema é que não estou conseguindo passar os parâmetros
enfim que bom que tu voltou
Hebert_Coelho
Coloca seu código como está do modo q eu falei para testar.
Tem que funcionar pois é um query normal.
jaissonduarte
classe modelo:
@Entity@Table(name="area")@XmlRootElement@NamedNativeQuery(name="Descricao",query="SELECT * FROM Area WHERE descricao ~* descricao")@NamedQueries({@NamedQuery(name="Area.findAll",query="SELECT a FROM Area a"),@NamedQuery(name="Area.findByCodigo",query="SELECT a FROM Area a WHERE a.codigo = :codigo"),@NamedQuery(name="Area.Descricaos",query="SELECT a FROM Area a WHERE a.descricao = :descricao")})publicclassAreaimplementsSerializable{privatestaticfinallongserialVersionUID=1L;publicstaticfinalStringpesquisarNamed="Area.Descricaos";publicstaticfinalStringpesquisarNativa="Descricao";@Id@Basic(optional=false)@NotNull@Column(name="codigo")privateIntegercodigo;@Basic(optional=false)@NotNull@Size(min=1,max=30)@Column(name="descricao")privateStringdescricao;
casse DAO:
@StatelesspublicclassAreaDAO{@PersistenceContext(name="pesquisaDocumentoPU")privateEntityManagerem;privateAreaarea;publicList<Area>pesquisar(Stringdescricao){List<Area>resultado=null;try{Queryconsulta=em.createNativeQuery("select * from area where descricao = descricao",Area.class);consulta.setParameter("descricao",descricao);resultado=consulta.getResultList();returnresultado;}catch(Exceptione){System.out.println("não deu hehehes: "+e.getMessage());}returnresultado;}}
Hebert_Coelho
Mano, novamente você não colocou os : Query consulta = em.createNativeQuery(“select * from area where descricao = descricao”, Area.class);
select * from area where descricao = :descricao
Isso aqui tem que funcionar.
jaissonduarte
só que não funciona :oops:
da esse erro:
Informações: não deu hehehes:
Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax error at or near ":"
Error Code: 0
Call: select * from area where descricao = :descricao
Query: ReadAllQuery(referenceClass=Area sql=“select * from area where descricao = :descricao”)
ricardobocchi
tenta
Query consulta = em.createNativeQuery("select * from area where descricao = ?", Area.class);
consulta.setParameter(1, descricao);
Informações: erro 1
Exception Description: The primary key read from the row [ArrayRecord(
=> 2
=> jaisson)] during the execution of the query was detected to be null. Primary keys must not contain null.
Query: ReadAllQuery(referenceClass=Area sql="select * from area where descricao = ?")
Obs.: 2, jaisson, são dados do bd
tenhamos fé
Hebert_Coelho
Cara, deu um erro muito bizarro agora: during the execution of the query was detected to be null. Primary keys must not contain null.
Verifique seu DB se tem algum ID com campo primário null.
Hebert_Coelho
Caso todos os ids estejam preenchido, tenta trocar de Integer para int o seu id.
OBS.: Essa alteração pode quebrar seu código em um monte de lugar.
jaissonduarte
cara não sei se isso ajuda mas quando eu aprendi persistência com JDBC, meu professor criou esses métodos:
publicList<Professor>getProfessores(Stringordem,Integercodigo,Stringnome)throwsClassNotFoundException,SQLException{List<Professor>professores=newArrayList<Professor>();Stringsql="SELECT * FROM professor WHERE 1=1 "+obtemFiltros(codigo,nome)+" ORDER BY "+ordem;PreparedStatementps=Conexao.getConexao().prepareStatement(sql);ResultSetrs=ps.executeQuery();while(rs.next()){Professorprofessor=newProfessor();professor.setCodigo(rs.getInt("codigo"));professor.setNome(rs.getString("nome"));professor.setSexo(Conversor.stringToChar(rs.getString("sexo")));professor.setDataAdmissao(ConverteData.enToBr(rs.getString("dt_admissao")));professor.setDataDemissao(ConverteData.enToBr(rs.getString("dt_demissao")));professores.add(professor);}returnprofessores;}privateStringobtemFiltros(Integercodigo,Stringnome){StringBuilderfiltro=newStringBuilder();if(codigo!=null){filtro.append(" AND codigo = "+codigo);}if(nome!=null){//.replaceAll("'", "") para todas as Strings senão//submeto ' or 1=1 or ''='filtro.append(" AND nome ~* '"+nome.replaceAll("'","")+"'");}returnfiltro.toString();}
gomesrod
Olá,
Só metendo o nariz onde não fui chamado
Por que recorrer a Native Query para uma consulta simples de listagem?
Fazendo dessa forma você não vai tirar proveito da facilidade do JPA, que é justamente encapsular a conversa com o banco e tirar do desenvolvedor a preocupação com SQL.
NativeQuery foi feito para casos específicos, por exemplo quando precisar otimizar a performance de uma consulta complexa.
Se no momento não estiver com tempo suficiente para aprender a utiliza-lo, é melhor utilizar JDBC puro mesmo… do jeito que está vc tem a complexidade do JPA (reparou quantos erros está dando? esse bicho é meio sensível rsrs) sem ter as vantagens que ele proporciona!
jaissonduarte
gomesrod:
Olá,
Só metendo o nariz onde não fui chamado
Por que recorrer a Native Query para uma consulta simples de listagem?
Fazendo dessa forma você não vai tirar proveito da facilidade do JPA, que é justamente encapsular a conversa com o banco e tirar do desenvolvedor a preocupação com SQL.
NativeQuery foi feito para casos específicos, por exemplo quando precisar otimizar a performance de uma consulta complexa.
Se no momento não estiver com tempo suficiente para aprender a utiliza-lo, é melhor utilizar JDBC puro mesmo… do jeito que está vc tem a complexidade do JPA (reparou quantos erros está dando? esse bicho é meio sensível rsrs) sem ter as vantagens que ele proporciona!
essa doeu , foi direto na alma
a gente só esta tentando fazer uma consulta normal para partir para o ~* que é próprio do Postresql
entendeu amigo,
gomesrod
Bom, espero que vc tenha entendido que não tive nenhuma intenção de ser grosseiro, né!
Agora de volta ao assunto:
De fato, o operador ~* é mais poderoso que um simples LIKE, pelo fato de ele fazer casamento de expressões regulares. Mas nesse caso, como você só quer verificar se contém a sequência desejada (não está usando recursos específicos de expressão regular), o like pode servir perfeitamente.
Só não esqueça dos curingas % antes e depois da palavra. Assim
// Query JPQL = SELECT a FROM Area a WHERE a.descricao like :descricao
query.setParameter("descricao", "%" + descricao + "%");
jaissonduarte
:oops: não, não, não que eu tenha achado “grosseiro”, é que foi engraçado, eu fazendo uma consulta simples para ver se o NativeQuery funcionava e pelo jeito não,
pois é como o ~* não funcionou eu desisti dele e estou usando o LIKE que por sinal esta bombando
valeu ao jakefrog que muito me ajudou, ao gomesrod e ao ricardobocchi
obrigado a todos mas eu vou usar o LIKE, fica para próxima o ~*
Hebert_Coelho
Senhor jaissonduarte, tudo bem?
Eu sumi daqui pq eu já estava sem saber oq fazer com relação ao seu problema. Geralmente nesses casos eu costumo pesquisar e escrever um post sobre o assunto.
Bem eu estou no momento escrevendo um post sobre JPA e consultas. Diversos modos de se fazer e tals. Vai ter umas 14 páginas! :shock:
Agora, só para botar lenha na fogueira, olha só o que eu acabei de fazer:
Eu mato a cobra e mostro o pau rapaz! :twisted: :twisted: :twisted:
Veja a versão do seu JDBC, a versão da implementação JPA que você está utilizando. Eu tive um erro bizarro ao declarar @NativeNamedQuery. Tente fazer do mesmo modo que eu postei ai e fale o resultado.