2012-06-12 11 views
6

Sono nuovo in JPA e ho un problema quando provo a eseguire una query sul database utilizzando la funzione MAX(). Il codice della mia funzione è il seguente. Qualcuno può aiutarmi? Grazie.Impossibile ottenere il valore corretto con la query SELECT utilizzando MAX() in JPA

public int getMaxId(){ 

    entityManager = this.entityManagerFactory.createEntityManager(); 

    Query query = entityManager.createQuery("SELECT * FROM user WHERE id = (SELECT MAX(u.id) FROM user u)"); 
    User user = (User) query.getSingleResult(); 

    int id = user.getId(); 
    return id; 
} 

Sto utilizzando JPA, TopLink e Apache Derby. Il mio metodo dovrebbe restituire l'id massimo degli utenti della tabella.

Edit: io chiamo quella funzione di un servizio:

try { 
     int id = userDAO.getMaxId(); 
     logger.info("Max id: " + id); 
     user.setId(id+1); 

    } 
    catch (Exception ex){ 
     logger.error("Unable to get the max id."); 
    } 

Valore della user.setId() è sempre '0'.

Edit (2): Log

Caused by: Exception [EclipseLink-8034] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.JPQLException 
Exception Description: Error compiling the query [SELECT u FROM user u WHERE u.id = (SELECT MAX(uu.id) FROM user uu)]. Unknown entity type [user]. 
    at org.eclipse.persistence.exceptions.JPQLException.entityTypeNotFound(JPQLException.java:483) 
    at org.eclipse.persistence.internal.jpa.parsing.ParseTreeContext.classForSchemaName(ParseTreeContext.java:138) 
    at org.eclipse.persistence.internal.jpa.parsing.SelectNode.getClassOfFirstVariable(SelectNode.java:327) 
    at org.eclipse.persistence.internal.jpa.parsing.SelectNode.getReferenceClass(SelectNode.java:316) 
    at org.eclipse.persistence.internal.jpa.parsing.ParseTree.getReferenceClass(ParseTree.java:436) 
    at org.eclipse.persistence.internal.jpa.parsing.ParseTree.adjustReferenceClassForQuery(ParseTree.java:75) 
    at org.eclipse.persistence.internal.jpa.parsing.JPQLParseTree.populateReadQueryInternal(JPQLParseTree.java:103) 
    at org.eclipse.persistence.internal.jpa.parsing.JPQLParseTree.populateQuery(JPQLParseTree.java:84) 
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:219) 
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:190) 
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:142) 
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:126) 
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1475) 
    ... 35 more 

mio entità User è dichiarato come segue:

@Entity 
@Table(name = "user") 
public class User { 

@Id 
private int id; 
private String name; 
private String lastName; 
private String city; 
private String password; 
+2

Suggerisco di utilizzare i valori ID generati. – JMelnik

+1

Non dovresti ingoiare l'eccezione, prova a usare 'ex.printStackTrace()' per stampare lo stack di errori completo per maggiori dettagli. –

+0

@JMelnik Sì, sono d'accordo ma volevo capire come funziona JPA/JPQL cercando di usare opreations e query persistenti. – Spacemonkey

risposta

20

È possibile utilizzare direttamente più semplice JPQL

return (Integer)entityManager.createQuery("select max(u.id) from User u").getSingleResult(); 

Oppure utilizzare TypedQuery

return entityManager.createQuery("select max(u.id) from User u", Integer.class).getSingleResult(); 

EDIT:

Unknown entity type [user] 

Si consiglia di utilizzare User invece di user.

+0

Grazie per la risposta. Ho provato a modificare il codice ma non restituisce ancora un valore. Quando provo a persistere qualsiasi oggetto, faccio questo e senza problemi. entityManager.getTransaction().begin(); entityManager.persist(user); entityManager.getTransaction().commit(); Ma i querys non funzionano ok, non so perché. – Spacemonkey

+0

@ Julián Non restituire il valore significa? il valore è sbagliato? –

+0

Ciao Pau, significa che la chiamata alla funzione getMaxId() solleva sempre catch() nel livello Servizio (vedi aggiornamento) – Spacemonkey

2

Beh, è ​​difficile da dire dai vostri commenti e non avete postato alcuna registrazione.

ne dite di questo:

Query query = entityManager.createQuery("SELECT u FROM users u WHERE u.id = (SELECT MAX(u.id) FROM users u)"); 
+0

più 1 sì funziona bene :) –

1

im utilizzando il codice:

Query qry = em.createQuery("SELECT MAX(t.column) FROM Table t"); 
    Object obj = qry.getSingleResult(); 
    if(obj==null) return 0; 
    return (Integer)obj; 

Causa se non ci sono elementi su Table "t", NullPointerException sta gettando.

-2

È una buona soluzione, ma è necessario utilizzare nomi diversi in due parti di sql. In questo modo: "SELECT u FROM users u WHERE u.id = (SELEZIONA MAX (u2.id) Dagli utenti u2)"

Problemi correlati