2012-06-12 25 views
6

Soy nuevo en JPA y tengo un problema cuando trato de consultar a la base de datos usando la función MAX(). El código de mi función es el siguiente. ¿Alguien puede ayudarme? Gracias.No se puede tener el valor correcto con la consulta SELECT usando MAX() en 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; 
} 

Estoy usando JPA, TopLink y Apache Derby. Mi método debe devolver la identificación máxima de los usuarios de la tabla.

Editar: Tiene la palabra que la función de un servicio:

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

Valor de user.setId() siempre es '0'.

Editar (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 

Mi entidad User se declara como sigue:

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

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

Sugiero usar los valores de ID generados. – JMelnik

+1

No debe tragar la excepción, intente usar 'ex.printStackTrace()' para imprimir la pila de error completa para más detalles. –

+0

@JMelnik Sí, estoy de acuerdo, pero quería entender cómo funciona JPA/JPQL al tratar de usar consultas y consultas persistentes. – Spacemonkey

Respuesta

20

usted puede utilizar directamente JPQL más sencilla

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

O utilice TypedQuery

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

EDIT:

Unknown entity type [user] 

Debe utilizar User en lugar de user.

+0

Gracias por su respuesta. He intentado modificar el código pero todavía no está devolviendo un valor. Cuando intento persistir cualquier objeto me gusta así y sin problemas. entityManager.getTransaction().begin(); entityManager.persist(user); entityManager.getTransaction().commit(); Pero las consultas no funcionan bien, no sé por qué. – Spacemonkey

+0

@ Julián No devolver valor significa? el valor es incorrecto? –

+0

Hola Pau, significa que la llamada a la función getMaxId() siempre provoca catch() en la capa de servicio (ver actualización) – Spacemonkey

2

Bueno, es difícil de decir por sus comentarios y no ha publicado ningún registro.

¿Qué tal esto:

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

más 1 sí, funciona bien :) –

1

Im usar ese código:

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

Porque si no hay elementos en la tabla "t", es tirar NullPointerException.

-2

Es una buena solución, pero debe usar nombres diferentes en las dos partes de sql. De esta forma: "SELECCIONAR DE LOS USUARIOS u DONDE u.id = (SELECCIONAR MAX (u2.id) DE USUARIOS u2)"

Cuestiones relacionadas