style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

[resuelto] Error en JPA con query a un elemento XML

Hola buenas jovenes ilustres tengo la siguiente situacion:

Estoy trabajando en un dashboard para la revision del estado de servicios web. Dicho dashboard se deploya en un JBOSS y este dashboard detecta que datasources estan configurados en el JBOSS.

Estoy utilizando JPA para el mapeo de las entidades, pero como cada servicio web tiene su propio schema y nombramiento de tablas no puedo utilizar anotaciones, asi que se estan utilizando mapeo en XML com los siguiente:

  <mapped-superclass class="Record">
    <attributes>
      <basic name="created">
        <column name="CREATE_DATE" nullable="false"/>
      </basic>
      <basic name="lastUpdated">
        <column name="UPDATE_DATE" nullable="false"/>
      </basic>
    </attributes>
  </mapped-superclass>
<entity class="ServiceTransactionDetail" name="ServiceTransactionDetail">
    <table name="TRANSACTION" />
    <attributes>
      <one-to-many name="outbounds" target-entity="ServiceOutbound" fetch="EAGER" >
        <order-by>sequence</order-by>
        <join-column name="REQUEST_ID" />
      </one-to-many>
    </attributes>
  </entity>

Este dashboard como lo mencione detecta los datasources por lo tanto tengo un servlet (por cierto esta en Spring) para cada datasource y toda la configuracion pertinente, repositorios, controllers, servicios, archivo ORM, y su persistence.xml y funciona muy bien, solo que me acabo de topar con un pequeño problema.

Uno de los servicios almacena informacion en un XML, se maneja Oracle como base de datos, asi que es un XMLType, tengo el siguiente query que en el cliente SQL funciona de maravilla:

SELECT
SUM (CASE WHEN STATUS = 'SUCCESS' THEN 1 ELSE 0 END) AS s_count,
SUM (CASE WHEN STATUS != 'SUCCESS' THEN 1 ELSE 0 END) AS e_count
FROM (
  SELECT i.response_body.EXTRACT('//ServiceResponse/status/text()').getStringVal() AS STATUS
  FROM MESSAGE_INBOUND i);                                                                                                                                                                                                                            

Pero al realizar un nativeQuery con JPA me lanza el siguiente error:

 for servlet text threw exception: java.sql.SQLException: Invalid SQL type: sqlKind = UNINITIALIZED
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:82) [ojdbc7-12.1.0.1.jar:12.1.0.1.0]
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:58) [ojdbc7-12.1.0.1.jar:12.1.0.1.0]
        at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:943) [ojdbc7-12.1.0.1.jar:12.1.0.1.0]
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1075) [ojdbc7-12.1.0.1.jar:12.1.0.1.0]
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3820) [ojdbc7-12.1.0.1.jar:12.1.0.1.0]
        at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3867) [ojdbc7-12.1.0.1.jar:12.1.0.1.0]
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1502) [ojdbc7-12.1.0.1.jar:12.1.0.1.0]
        at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:462)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:56) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3
]
        at org.hibernate.loader.Loader.getResultSet(Loader.java:2040) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1837) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1816) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.Loader.doQuery(Loader.java:900) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.Loader.doList(Loader.java:2526) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.Loader.doList(Loader.java:2512) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2342) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.Loader.list(Loader.java:2337) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1833) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:231) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:157) [hibernate-core-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]
        at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:268) [hibernate-entitymanager-4.2.7.SP1-redhat-3.jar:4.2.7.SP1-redhat-3]

He estado buscando en la red esa exception java.sql.SQLException: Invalid SQL type: sqlKind = UNINITIALIZED pero no hay nada relacionado a XMLType o almenos como lo he buscado no lo he encontrado.

No se si alguno de uds me pudiera guiar o si ya se a topado con esto me pueda pasar una fuente donde me pueda guiar.

Saludos y gracias de antemano!

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Pequeña duda

Pregunta: ¿a que te refieres con el «cliente SQL»? ¿Te refieres a algún programa que incluye junto con la base de datos de Oracle?

Si puedes ejecutar esta consulta con JDBC simple, seguro también JPA puede hacerlo. Es posible obtener el objeto java.sql.Connection desde JPA.

~~~

Imagen de arterzatij

Asi es el cliente es un

Asi es el cliente es un Toad.

Y esa referencia no me funciona pues no estoy utilizando hibernate, ya que tengo un entity que puede ser utilizado por varios datasources y los archivos ORM son los que mapean a las entidades con las tablas de los diferentes esquemas. El sistema tiene una configuracion para una carga lazy, pues hasta que se detectan los datasources instalados en el JBOSS (esto es asi, pues se puede deployar en cualquier servidor y detecta los servicios que tenga el servidor) y solo se desea que se carguen los servlets que pertenezcan a los datasources.

Pero gracias por la referencia jpaul.

Sólo por curiosidad...

Sólo por curiosidad... ¿Qué implementación de JPA estás usando? p.ej., OpenJPA, EclipseLink JPA, DataNucleus, etc. ¿Qué versión de JBoss?

Imagen de arterzatij

El server : JBOSS 6.2 y JPA

El server :

JBOSS 6.2
y JPA se esta utilizando la implementacion que trae JBOSS

Entonces sí...

 

Mmm... Entonces estás usando Hibernate. Respecto al problema que tienes entre manos, ¿qué hay de utilizar un procedimiento almacenado?

No estoy del todo familiarizado con las funciones de Oracle XML DB, pero ¿puedes utilizar tales funciones fuera de un PL/SQL? Precisamente por eso te decía que si podías ejecutar esa consulta con JDBC simple, entonces JPA podría hacerlo también.

~~~

Imagen de arterzatij

Si pero muy en el fondo (de

Si pero muy en el fondo (de hecho solo lo uso para declarar la conexion y el dialecto) pero los xml de configuracion (mapeo y persistencias de unidad son JPA), en el codigo java estoy utilizando unicamente las intefaces de persistecia (JPA) y no tengo acceso a la db como para un procedimeinto, de hecho estoy algo limitado :'(, asi esta los lineamientos de la codificacion.

Imagen de arterzatij

Bueno despues de tanto buscar

Bueno despues de tanto buscar y hacer ritos a seres divinos, unas chelas, un peyotazo y el ojo bionico de un compañero:

code no tan bueno
String query = "SELECT" +
                "SUM (CASE WHEN status = ? THEN 1 ELSE 0 END) AS s_count," +
                "SUM (CASE WHEN status != ? THEN 1 ELSE 0 END) AS e_count" +
                "FROM ( " +
                "       SELECT i.response_body.EXTRACT('//ServiceResponse/status/text()').getStringVal() AS STATUS" +
                "       FROM MESSAGE_INBOUND i" +
                ")";
code bueno
String query = "SELECT " +  // <- espacio aqui
                "SUM (CASE WHEN status = ? THEN 1 ELSE 0 END) AS s_count, " + // <- espacio aqui (no tan encesario pero bueno)
                "SUM (CASE WHEN status != ? THEN 1 ELSE 0 END) AS e_count " + // <- espacio aqui
                "FROM ( " +
                "       SELECT i.response_body.EXTRACT('//ServiceResponse/status/text()').getStringVal() AS STATUS " + // <- y espacio aqui
                "       FROM MESSAGE_INBOUND i " +
                ")";

Si son algo observadores cosa que no fue en mi, resulta que estaba omitiendo algunos espacios en mi query, y por esa razon me lanzaba dicha exception. Es lamentable que un motor de BD tan caro no te pueda dar mensajes de error mas objetivos, que tiene que ver un query mal formado con un tipo de dato. Pero en fin ya quedo que es lo bueno, otra cosa a considerar es que no debe llevar un ";" al final si no te lanza una exception, asociada a query no terminado adecuadamente.

Otra cosa que me queda para la siguiente colocar el codigo que genera la query en Java en lugar del query creo que dara mas informacion, para mis homologos con mejor ojo!

Gracias por el apoyo!

SQLinForm

 

También puedes usar SQLinForm para darle formato a tu consulta y además generar un fragmento de código con ésta.

~~~

Imagen de arterzatij

humm nice muchas gracias, no

humm nice muchas gracias, no lo conocia, con esto de las cosas modernas de los ORM, se van olvidando las practicas de sql en el codigo JAVA.

Como no genera código con

Como no genera código con StringBuilder, sólo habría que cambiar el StringBuffer por el StringBuilder.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">