2012-09-11 8 views
14

la mia domanda èJava Persistence SQL nativo non accettare parametri

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();' 

Quando eseguo questo, ottengo un errore

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

come è il gruppo in base ai parametri di input mancanti –

+4

@alfasin: solo perché esiste una funzione 'aggregate' non significa necessariamente che sia necessario un' GROUP BY'. Le funzioni di aggregazione "spesso" (non sempre) richiedono un'istruzione 'GROUP BY' aggiunta. – Annjawn

+0

Sono relativamente nuovo alla persistenza. C'è qualche errore di sintassi che sto facendo? Ho un pezzo simile di codice che funziona quando la query viene creata utilizzando l'API em.createQuery(). –

risposta

18

La seguente soluzione dovrebbe funzionare:

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(); 

E ' sembra che se usi i parametri posizionali funzionerà. Non è possibile combinare parametri con nome e query nativa. Qui ci sono alcuni link:

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

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

E molti altri, solo Google per: "Solo parametro posizionale vincolante può essere portabile utilizzato per le query native".

EDIT: più collegamenti a domande con problemi simili:

How to get all the element from JDBC query

JPA/Hibernate Native Queries do not recognize Parameters

2

Questo articolo è stato davvero utile!

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

Il senso di questo articolo è:

Questi sono non sicuri query, non usarlo! La concatenazione di stringhe è male:

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(); 

Questi sono sicuri query.

/* 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

In JPA

quando si utilizza questo: interrogazione

query = em. createNativeQuery (sql);

è necessario impostare l'indice per i parametri impostati. Si noti che la query ha più di un parametro.