org.hibernate.exception.SQLGrammarException: could not execute query
Buenos días a todos,
soy nuevo en hibernate.
Tengo un problema con hibernate ya que en las tablas en las que estoy trabajando no hay ninguna relación referencial y una de ellas no tiene llaves primarias (tabla2). No puedo cambiar el modelo ya que es de una empresa y no medan esta opción, a demás es altamente impactante.
Actualmente estoy manejando los query con la utilidad nativa por inconvenientes anteriormente presentados por criterial y query.
Me aparece el error expuesto en el foro pero ya he intentado todo para desarrollarlo, recuerden que el problema radica que las tablas manejadas no tienen integridad referencial y además tienen ambas entidadades columnas con el mismo nombre.
Describo lo que he hecho actualmente para dar solución al problema:
1) Utilice addEntity() para agregar el alias que utiliza la tabla.
2) Sin utilizar addEntity tampoco funciona
3) En la construcción de los resultados de la sentencia realizo la siguiente transformación consulta.setResultTransformer( Transformers.aliasToBean( clase ) );
4) para que no hallan problemas con los atributos traidos del select se agregan todos los atributos de las tablas con sus respectivos alias con el método addscalar();
5) He seteado los parámetros son setParameter y setString pero no se soluciona el problema
6) Lo único raro que veo en hibernate es que la sentencia transformada para el los parámetros aparecen con el signo de interrogación, aunque estos esten en la sentencia inicial
A continuación doy los soportes para evaluar el problema:
PruebaUsuario.main() construcción sentencia después de escalar los atributos : SELECT {tx.*}, {o.*} FROM co.modelo.Hibernate.pojos.tabla1 tx, co.modelo.Hibernate.pojos.tabla2 o WHERE tx.ety = o.ety AND tx.ordid = o.ordid AND tx.servicio = o.servicio AND tx.ety = :ety AND o.perid = :ref1 AND tx.estado = 'CAPTURADA' AND TRUNC(SYSDATE) >= tx.fechasolicitud + :dias AND o.dreferencia2 = :ref2 AND o.dreferencia3 = :ref3
Hibernate: SELECT tx.tickid as tickid0_0_, tx.ordid as ordid0_0_, tx.fechasolicitud as fecsolic3_0_0_, tx.logfechaproceso as fecproce4_0_0_, tx.valor as valor0_0_, tx.valor2 as valor26_0_0_, tx.estado as estado0_0_, tx.codtx as codtx0_0_, tx.bank as bank0_0_, tx.ety as ety0_0_, tx.servicio as servicio0_0_, tx.ciclo as ciclo0_0_, tx.pagosys as pags13_0_0_, tx.prlg_Code as prlg14_0_0_, tx.ref_Match as ref15_0_0_, tx.filtro as filtro0_0_, tx.logcmpuno as logcmpuno0_0_, tx.idgroup as idgroup0_0_, tx.sendmail as sendmail0_0_, tx.lggcode as lggcode0_0_, o.ety as ety1_1_, o.ordid as ordid1_1_, o.perid as perid1_1_, o.servicio as servicio1_1_, o.dvalor as dvalor1_1_, o.dvalor2 as dvalor26_1_1_, o.destado as destado1_1_, o.ordqty as ordqty1_1_, o.dtot as dtot9_1_1_, o.dref2 as dref10_1_1_, o.dref3 as dref11_1_1_, o.dcom as dcom1_1_, o.dfecha as dfecha1_1_, o.dfechareal as dfecr14_1_1_, o.dflag_Dbcr as dflag15_1_1_, o.dsrvcurrency as dsrvc16_1_1_, o.dpagcurrency as dpagc17_1_1_, o.dvaltrm as dvaltrm1_1_, o.dconsecutivo as dconse19_1_1_ FROM co.modelo.Hibernate.pojos.Tabla1 tx, co.modelo.Hibernate.pojos.Tabla2 o WHERE tx.ety = o.ety AND tx.ordid = o.ordid AND tx.servicio = o.servicio AND tx.ety = ? AND o.perid = ? AND tx.estado = 'CAPTURADA' AND TRUNC(SYSDATE) >= tx.fechasolicitud + ? AND o.dreferencia2 = ? AND o.dreferencia3 = ?
Error:
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.doList(Loader.java:2235)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
at org.hibernate.loader.Loader.list(Loader.java:2124)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:312)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1723)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:175)
at co.modelo.hibernate.DAO.PruebaUsuario.main(PruebaUsuario.java:167)
Caused by: java.sql.SQLException: ORA-00933: comando SQL no terminado correctamente
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteDescribe(TTC7Protocol.java:830)
at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2391)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2672)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:527)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1812)
at org.hibernate.loader.Loader.doQuery(Loader.java:697)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2232)
... 7 more
Agradezco si depronto existe alguna solución al problema o si defenitivamente por el modelo de la base de datos no se puede dar solución.
Gracias por sus respuestas.
- DragonNegro's blog
- Inicie sesión o regístrese para enviar comentarios
Comentarios
Como que estás usando la
Como que estás usando la sintaxis de un query nativo con sintaxis de HQL no?
Lo digo por el nombre de las tablas, que pones las clases de Hibernate, y porque pones éso de
{tx.*}, {o.*}
o igual yo no lo he trabajado así ...Porqué no pruebas haciendo la consulta directamente en tú navegador de base de datos, y cuando te salga ahí, la traspasas a código Java.
SQLGrammarException
Como estaba comentando como la base de datos tiene una mala integridad referencial como la tabla tabla2 que tiene llave foránea pero no primaría, pues la única forma que me funciono en otro query que realiza la aplicación fue realizandolo en código nativo y logicamente que solamente se involucra solamente una tabla en el query a diferencia del actual que es tresmil veces más complejo a mi percepción .
La explicación de la utilización de {tx.*}..., según lo que he encontrado en internet cuando dos entidades tienen nombres de columnas iguales la alternativa es agregar los métodos addEntity("alias", clase) y adicionalmente para que no falle la sentencia hay que colocar los alias de las tablas en el select así como se encuentran actualmente el primer select expuesto en el caso.
El select inicial que construyo para pasarlo por parámetro al método createSQLQuery y luego ejecutarlo en con el método .list() si lo ejecuto en la base de datos corre correctamente y trae la información que estoy buscando pero si lo desarrollo en hibernate siempre me sale el error anteriormente expuesto.
Si realizo la metodología estandar que es con la clase Query no me funciona ya que me retorna el primer registro duplicado por la cantidad de coincidencias que existen en el query (Estas coincidencias son tuplas distintas de la base de datos), por lo tanto la información que trae se duplica y no se encuentra completa como la trae el Query.
Pero si existe otra manera de realizar este tipo de sentencia para tablas con integridad referencial pobre, agradecería si me lo hicieran saber para realizar las pruebas, por que creo que he intentado todo.
Gracias por la atención y respuesta dadas.
Puedes usar BrainLeg Solo
Puedes usar BrainLeg
Solo pega tu excepción y busca
Por éso..
A poco si corres:
En tu navegador de base de datos si corre? con todo y los nombres calificados de las clases?
Ya realice modificaciones y nada
Quite los corchetes del query ( {tx.*}...) ejecuto el query actualizado en la BD y funciona y en hibernate presenta el mismo error.
...
A ver, postea tus entidades, por favor, entre los tags de <code>.
Código de la aplicación
Entidad tabla1
Mapeo de la entidad tabla1
Entidad tabla2 java
Mapeo de la Entidad
Archivo de configuracion
Prueba
Ya probaste hacer algo en HQL sencillo del estilo:
Así sin condiciones?
Prueba no funciona
Realice la prueba con la siguiente sentencia
Desde un cliente sql se ejecuta en la base de datos de la siguiente manera:
Si funciona desde el cliente Oracle
y
No funciona desde el cliente Oracle
Por ende ejecuto la siguiente sentencia desde el programa:
Y sigue presentando el error.
:-S
Lo que yo no entiendo, es porqué usas los nombres calificados de las clases, para ejecutar consultas sobre tablas, en Oracle.
Lo que tú tienes como:
Según tú mapeo de Hibernate el reflejo en SQL, debería de ser:
en HQL sería algo como:
Por éso preguntaba al principio si corre tu sentencia, porque se no me cae que uses nombres calificados de clase en un navegador de base de datos :-S
Deberías de estandarizar tu sentencia, si la vas a aplicar en SQL, pues sólo usa SQL con toda la bola de atributos que enumeraste al principio, si lo haces con Hibernate, asegúrate que tus entidades esten correctamente mapeadas y sólo usa notación de objetos como dice la documentación.
Solucionado.
Sí usted tiene toda la razón la sentencia que estaba ejecutando con el nombre de las clases calificadas no me funcionaba en hibernate, pues aunque no es una justificación, pero soy totalmente novato en el tema, pensé que las entidades en la sentencia se debia colocar con los nombres de la clases calificadas dentro del código en hibernate y cuando lo corria en el cliente sql le quitaba toda la ruta de las clases por ende siempre me funcionaba en el cliente.
Creo que este fue un error muy ingenuo de mi parte.
Por ende aclaro que la sentencia que se encuentra a continuación es la incorrecta:
Queda totalmente claro que jamás en una sentencia en hibernate se deben dejar las entidades con sus clases calificadas sino se deben dejar solamente el nombre de los objetos. Se muestra a continuación el query que funciono correctamente:
Gracias por su colaboración.