2012-06-12 18 views
6

Ich bin neu in JPA und ich habe ein Problem, wenn ich versuche, Abfrage der Datenbank mit MAX() -Funktion. Code meiner Funktion folgt. Kann mir jemand helfen? Vielen Dank.Kann nicht korrekt Wert mit SELECT-Abfrage mit 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; 
} 

Ich verwende JPA, TopLink und Apache Derby. Meine Methode sollte die maximale ID der Tabellenbenutzer zurückgeben.

Edit: Ich nenne diese Funktion von einem Dienst:

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."); 
    } 

Wert von user.setId() ist immer '0'.

Edit (2): Anmelden

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 

Meine Einheit User erklärt sich wie folgt:

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

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

Ich empfehle die Verwendung von generierten ID-Werten. – JMelnik

+1

Sie sollten die Ausnahme nicht verschlucken, verwenden Sie 'ex.printStackTrace()', um den vollständigen Fehler-Stack für weitere Details zu drucken. –

+0

@JMelnik Ja, ich stimme zu, aber ich wollte verstehen, wie JPA/JPQL es versucht, persistente Operationen und Abfragen zu verwenden. – Spacemonkey

Antwort

20

Sie direkt einfacher JPQL

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

Oder TypedQuery verwenden können

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

EDIT:

Unknown entity type [user] 

sollten Sie User anstelle von user.

+0

Danke für Ihre Antwort. Ich habe versucht, den Code zu ändern, aber es gibt immer noch keinen Wert zurück. Wenn ich versuche, irgendein Objekt zu erhalten, mag ich das und ohne Probleme. entityManager.getTransaction().begin(); entityManager.persist(user); entityManager.getTransaction().commit(); Aber Abfragen funktionieren nicht ok, ich weiß nicht warum. – Spacemonkey

+0

@ Julián Nicht zurückgegebener Wert bedeutet? der Wert ist falsch? –

+0

Hallo Pau, bedeutet, dass der Aufruf der Funktion getMaxId() catch() immer in der Service-Schicht auslöst (siehe Update) – Spacemonkey

2

Nun, es ist schwer aus Ihren Kommentaren zu sagen und Sie haben keine Protokollierung gepostet.

Wie wäre es damit:

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

plus 1 ja es funktioniert gut :) –

1

Im diesen Code verwenden:

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

Ursache, wenn es keine Elemente auf Tabelle "t" ist, wird Nullpointer werfen.

-2

Es ist eine gute Lösung, aber Sie müssen verschiedene Namen in zwei Teile von SQL verwenden. Wie folgt: "SELECT u FROM Benutzer u WHERE u.id = (SELECT MAX (u2.id) FROM Benutzer u2)"