Necesita ayuda para crear JPA criterios de consulta

Estoy construyendo mi primer Java EE aplicación web utilizando Glassfish y JSF. Soy bastante nuevo a la consulta de criterios y tengo una consulta tengo que realizar, pero la javaee6 tutorial parece un poco delgada en ejemplos. De todos modos, estoy teniendo un duro momento de la creación de la consulta.

Objetivo: quiero sacar a la compañía con la mayoría de los documentos almacenados.
Las empresas tienen un OneToMany relación con los Documentos.
Documentos tiene una relación ManyToOne con varias mesas, el «usertype» columna distingue.

Consulta de MySQL:

SELECT USERID, COUNT(USERID) AS CNT 
FROM DOCUMENTS 
WHERE USERTYPE="COMPANY" 
GROUP BY USERID 
ORDER BY CNT DESC

Gracias

–update–
Basado en comentarios de los usuarios, aquí es lo que tengo hasta ahora:

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Documents> cqry = cb.createQuery(Documents.class);
        //Intersting Stuff
        Root<Documents> root = cqry.from(Documents.class);
        Expression userid = root.get("userID");
        Expression usertype = root.get("userType");
        Expression count = cb.count(userid);
        cqry.multiselect(userid, count);
        Predicate userType = cb.equal(usertype, "COMPANY");
        cqry.where(userType);
        cqry.groupBy(userid);
        cqry.orderBy(cb.desc(count));
        //more boilerplate
        Query qry = em.createQuery(cqry);
        List<Documents> results = qry.getResultList();

El error que me sale es:

Exception Description: Partial object queries are not allowed to maintain the cache or be edited.  You must use dontMaintainCache().

Error típico, no significa nada para mí!

Trate de escribir la consulta de CriteriaQuery<Documentos> CriteriaQuery con el fin de seleccionar la cantidad sin ofender a la API. Si usted también publicar más información acerca de las tablas de entidades o puedo intentar algunas otras formas de

OriginalEl autor Alan B. Dee | 2012-01-06

3 Kommentare

  1. 21

    Su consulta no devuelve un completa entidad objeto como usted sólo elegir a los dos campos de la tabla (esta es la razón por la que usted está recibiendo un error que dice yadayadapartialyadayada).

    Su solución es casi correcto, aquí está lo que necesitas cambiar para hacer que funcione—lo que es parcial.

    Lugar de una llanura CriteriaQuery<...> usted tiene que crear un tupla CriteriaQuery<..> llamando CriteriaBuilder.createTupleQuery(). (Básicamente, usted puede llamar a CriteriaBuilder.createQuery(...) y pasar Tuple.class como un argumento. Tuple es una especie de comodín clase de entidad.)

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Tuple> cq= cb.createTupleQuery();
    
    Root<Documents> root = cq.from(Documents.class);
    Expression<Integer> userId = root.get("USERID");
    Expression<String> userType = root.get("USERTYPE");
    Expression<Long> count = cb.count(userId);
    
    cq.multiselect(userId.alias("USERID"), count.alias("CNT"));
    cq.where(cb.equal(userType, "COMPANY");
    cq.groupBy(userId);
    cq.orderBy(cb.desc(count));
    
    TypedQuery<Tuple> tq = em.createQuery(cq);
    for (Tuple t : tq.getResultsList()) {
      System.out.println(t.get("USERID"));
      System.out.println(t.get("CNT"));
    }

    (Acceso a los campos de un Tuple me dio un error si yo no uso de alias para ellos (en multiselect(...)). Esta es la razón por la que yo he utilizado alias, pero esto puede ser abordado de una manera más limpia mediante el uso de JPA 2 Metamodelo de la API de, que se describe en la especificación muy a fondo. )

    La documentación para CriteriaQuery.multiselect(...) describe el comportamiento de las consultas que utilizan Tuple objetos más profundamente.

    Genial! Se trabajó con casi la derecha de la caja. Entre esto y el artículo de @Mechkov compartida tengo una mucho mejor comprensión de los criterios de las consultas. Gracias.
    Buena respuesta, ayudó a resolver mi problema con el siguiente error You must use dontMaintainCache()
    Gracias por tu ejemplo de código. He aprendido mucho acerca de jpa criterios de las consultas con tuplas (en lugar de Entidades).
    Hola, quiero crear un alias para el cb.count(id de usuario) y el uso de alias en la posterior orden por la que se referirá a los alias. Es eso posible?
    Que hacer algo como esto. Definir el alias en la multiselect llamada.

    OriginalEl autor Kohányi Róbert

  2. 2

    Si usted está usando Hibernate, esto debería funcionar:

    ProjectionList pl = Projections.projectionList()
    .add(Projections.groupProperty("userid"))
    .add(Projections.property("userid"))
    .add(Projections.count("userid"));
    
    Criteria criteria = session.createCriteria(Document.class)
    .add(Restrictions.eq("usertype",usertype))
    .setProjection(pl)
    .addOrder(Order.desc("cnt"));

    Espero que ayude!

    Esto significa que el uso de Hiberate, que está fuera del ámbito de este capítulo. Al menos debe hablar de esto.
    sí, me temo que no voy a usar Hibernate. aunque estoy empezando a desear que fuera!
    oh, grandes disculpas. No se dio cuenta de eso!

    OriginalEl autor Gonzalo

  3. 0

    Echa un vistazo a este sencillo tutorial. Utiliza JPA2 y Criterios de

    http://www.jumpingbean.co.za/blogs/jpa2-criteria-api

    Saludos!

    El tutorial que has publicado es buena, pero la consulta que el OP quiere plantea una pregunta interesante: es la API de Criterios muy útil cuando la consulta devuelve los objetos de diferentes tipos?
    gracias, el tutorial me ha ayudado mucho. En cuanto a los diferentes tipos de todo lo que necesito es el identificador (de largo).
    Fresco. Me alegro ayudó. He utilizado yo mismo, no hace mucho tiempo.

    OriginalEl autor Mechkov

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea