2012-06-12 9 views
6

Jestem nowy w JPA i mam problem, gdy próbuję wysłać zapytanie do bazy danych za pomocą funkcji MAX(). Kod funkcji jest następujący. Czy ktoś może mi pomóc? Dziękuję Ci.Nie można uzyskać poprawnej wartości za pomocą zapytania SELECT za pomocą MAX() w 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; 
} 

Używam JPA, TopLink i Apache Derby. Moja metoda powinna zwracać maksymalny identyfikator użytkowników tabel.

Edit: Ja nazywam tę funkcję z usługi:

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

Wartość user.setId() zawsze jest '0'.

Edit (2): Zaloguj

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 

Moja jednostka User jest zadeklarowana następująco:

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

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

Proponuję użyć wygenerowanych wartości ID. – JMelnik

+1

Nie powinieneś przełamać wyjątku, spróbuj użyć 'ex.printStackTrace()', aby wydrukować pełny stos błędów, aby uzyskać więcej szczegółów. –

+0

@JMelnik Tak, zgadzam się, ale chciałem zrozumieć, w jaki sposób JPA/JPQL działa, próbując użyć trwałych operacji i zapytań. – Spacemonkey

Odpowiedz

20

można bezpośrednio użyć bardziej proste JPQL

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

lub użyj TypedQuery

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

EDIT:

Unknown entity type [user] 

Należy użyć User zamiast user.

+0

Dziękuję za odpowiedź. Próbowałem zmodyfikować kod, ale nadal nie zwraca wartości. Kiedy staram się utrzymywać dowolny obiekt, to lubię to i bez problemów. entityManager.getTransaction().begin(); entityManager.persist(user); entityManager.getTransaction().commit(); Ale kwerendy nie działają poprawnie, nie wiem dlaczego. – Spacemonkey

+0

@ Julián Nie zwraca wartości oznacza? wartość jest nieprawidłowa? –

+0

Witaj Pau, oznacza, że ​​wywołanie funkcji getMaxId() zawsze podnosi catch() w warstwie Service (zobacz aktualizację) – Spacemonkey

2

Trudno powiedzieć z waszych komentarzy i nie wysłano żadnego rejestru.

Jak o tym:

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

plus 1 tak to działa dobrze :) –

1

Im Używając tego kodu:

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

Bo jeśli nie ma żadnych elementów na stole "t", NullPointerException rzuca.

-2

To dobre rozwiązanie, ale trzeba użyć różnych nazw w dwóch częściach sql. W ten sposób: "WYBIERZ U OD UŻYTKOWNIKÓW u GDZIE u.id = (WYBIERZ MAKSYMALNY (u2.ID) OD użytkowników u2)"