2012-09-11 60 views
14

mi consulta espersistencia de Java SQL nativo no aceptar parámetros

sql = "SELECT SUM(TOTAL_BYTES_DELIVERED)/SUM(TOTAL_TIME_TAKEN_IN_DELIVERY) 
     FROM MV_MFT_TRANSFER 
     WHERE TRANSFER_INITIATION_TIME > :startDate 
      AND TRANSFER_INITIATION_TIME < :endDate" 

Query query = em.createNativeQuery(sql); 
query.setParameter("startDate", startDate, TemporalType.DATE); 
query.setParameter("endDate", endDate, TemporalType.DATE); 
query.getResultList();' 

Cuando ejecuto esto, me sale un error

SQLExceptionTHrown: 
<Sep 11, 2012 12:50:46 PM PDT> <Warning> <EclipseLink> <BEA-2005000> <2012-09-11 12:50:46.893--UnitOfWork(1387841584)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20120804-d768c4f): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: java.sql.SQLException: Missing IN or OUT parameter at index:: 1 
Error Code: 17041 
Call: SELECT SUM(TOTAL_BYTES_DELIVERED)/SUM(TOTAL_TIME_TAKEN_IN_DELIVERY) FROM MV_MFT_TRANSFER WHERE TRANSFER_INITIATION_TIME > :startDate AND TRANSFER_INITIATION_TIME < :endDate 
Query: DataReadQuery(sql="SELECT SUM(TOTAL_BYTES_DELIVERED)/SUM(TOTAL_TIME_TAKEN_IN_DELIVERY) FROM MV_MFT_TRANSFER WHERE TRANSFER_INITIATION_TIME > :startDate AND TRANSFER_INITIATION_TIME < :endDate")> 
***SQLException in init() TRANSFER METRICS BEAN**** 
Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20120804-d768c4f): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: java.sql.SQLException: Missing IN or OUT parameter at index:: 1 
+1

cómo es el grupo por parámetros de entrada faltantes –

+4

@alfasin - simplemente porque hay una función 'aggregate' no significa necesariamente que requiere un' GROUP BY'. Las funciones agregadas "a menudo" (no siempre) necesitan una declaración 'GROUP BY'. – Annjawn

+0

Soy relativamente nuevo en la persistencia. ¿Hay algún error de sintaxis que estoy haciendo? Tengo un fragmento similar de código que funciona cuando la consulta se crea usando la API em.createQuery(). –

Respuesta

18

La siguiente solución debería funcionar:

sql = "SELECT SUM(TOTAL_BYTES_DELIVERED)/SUM(TOTAL_TIME_TAKEN_IN_DELIVERY) 
     FROM MV_MFT_TRANSFER 
     WHERE TRANSFER_INITIATION_TIME > ? 
      AND TRANSFER_INITIATION_TIME < ?" 

Query query = em.createNativeQuery(sql); 
query.setParameter(1, startDate, TemporalType.DATE); 
query.setParameter(2, endDate, TemporalType.DATE); 
query.getResultList(); 

Se parece que si usa parámetros posicionales funcionará. No puede combinar los parámetros con nombre y la consulta nativa. Estos son algunos enlaces:

http://java.boot.by/scbcd5-guide/ch08s05.html

http://www.wisegeek.com/what-are-native-queries.htm

y muchos más, sólo Google para: "Sólo la unión parámetro de posición se puede usar de forma portátil para las consultas nativas".

EDIT: Más enlaces a las preguntas con problemas similares:

How to get all the element from JDBC query

JPA/Hibernate Native Queries do not recognize Parameters

2

Este artículo fue muy útil!

http://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-persistence-api-jpa

La esencia del artículo es:

Estos son inseguras consultas, no lo use! La concatenación de cadenas es malo:

List results = entityManager.createQuery("Select order from Orders order where order.id = " + orderId).getResultList(); 
List results = entityManager.createNativeQuery("Select * from Books where author = " + author).getResultList(); 
int resultCode = entityManager.createNativeQuery("Delete from Cart where itemId = " + itemId).executeUpdate(); 

Estos son seguras consultas.

/* positional parameter in JPQL */ 
Query jpqlQuery = entityManager.createQuery("Select order from Orders order where order.id = ?1"); 
List results = jpqlQuery.setParameter(1, "123-ADB-567-QTWYTFDL").getResultList(); 

/* named parameter in JPQL */ 
Query jpqlQuery = entityManager.createQuery("Select emp from Employees emp where emp.incentive > :incentive"); 
List results = jpqlQuery.setParameter("incentive", new Long(10000)).getResultList(); 

/* named query in JPQL - Query named "myCart" being "Select c from Cart c where c.itemId = :itemId" */ 
Query jpqlQuery = entityManager.createNamedQuery("myCart"); 
List results = jpqlQuery.setParameter("itemId", "item-id-0001").getResultList(); 

/* Native SQL */ 
Query sqlQuery = entityManager.createNativeQuery("Select * from Books where author = ?", Book.class); 
List results = sqlQuery.setParameter(1, "Charles Dickens").getResultList(); 
0

En JPA

cuando se utiliza este: consulta

consulta = em. createNativeQuery (sql);

debe establecer el índice para establecer los parámetros. Tenga en cuenta que su consulta tiene más de un parámetro.

Cuestiones relacionadas