entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

1voto

Consulta JPA a multiples tablas utilizando CriteriaBuilder

Buenas estoy tratando de realizar una consulta SQL mediante la api de CriteriaBuilder, la consulta sql que quiero realizar debe mostrar campos obtenidos de diferentes tablas y eso es lo que no se como hacer, una consulta de ejemplo podría ser la siguiente, aunque me valdría cualquier ejemplo que reúna campos de distintas tablas aunque sea mas sencillo que esta que pongo aquí.

select c.NOMBRE, sum(vl.IMPORTETOTAL) from ges_venta_lineas as vl, ges_producto as p, ges_modelo as m, ges_categoria as c where vl.producto_id=p.ID and p.modelo_id=m.ID and m.categoria_id=c.ID and vl.CREATION_DATE< X and vl.CREATION_DATE>Y group by m.categoria_id

He leído que una posible solución es utilizar el método createTupleQuery y la clase Tuple perteneciente a JPA que permite almacenar todos los posibles campos que queramos obtener de la consulta y manejarlos mediante un alias, por ejemplo para una consulta sencilla como esta:

select ges_venta_lineas.producto_id as producto, sum(ges_venta_lineas.IMPORTETOTAL) as suma from ges_venta_lineas group by ges_venta_lineas.producto_id

se hace de la siguiente manera:

CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq= qb.createTupleQuery();
Root<VentaLinea> root = c.from(VentaLinea.class);
Expression<BigDecimal> sum = qb.sum(root.get(VentaLinea_.importeTotal));
c.multiselect(root.get(VentaLinea_.producto).alias("producto"), sum.alias("suma"));
c.groupBy(root.get(VentaLinea_.producto));

Pero a la hora de mezclar campos de distintas tablas no consigo dar con la tecla, espero haberme explicado :)
Un saludo

1 Respuesta

1voto

Javi2EE Puntos6630

Vale ya lo he solucionado, gran parte del problema venía de que estaba invocando un método antiguo que no era sobre el que estaba trabajando y nada de lo que hacía me producía ningún cambio, cosas que pasan cuando te tiras demasiadas horas programando y que he notado nada mas ponerme hoy :)

Dejo aquí la solución.

select c.NOMBRE, sum(vl.IMPORTETOTAL) from ges_venta_lineas as vl, ges_producto as p, ges_modelo as m, ges_categoria as c where vl.producto_id=p.ID and p.modelo_id=m.ID and m.categoria_id=c.ID group by m.categoria_id
    public List<Tuple> getResumen(){
        CriteriaBuilder qb = em.getCriteriaBuilder();
        CriteriaQuery<Tuple> cq= qb.createTupleQuery();

        Root<VentaLinea> ventalinea = cq.from(VentaLinea.class);
        Root<Producto> producto = cq.from(Producto.class);    
        Root<Modelo> modelo = cq.from(Modelo.class);
        Root<Categoria> categoria = cq.from(Categoria.class);
        Expression<BigDecimal> sum = qb.sum(ventalinea.get(VentaLinea_.importeTotal));
        List<Predicate> predicates = new ArrayList<Predicate>();
        predicates.add(qb.equal(ventalinea.get(VentaLinea_.producto), producto));
        predicates.add(qb.equal(producto.get(Producto_.modelo), modelo));
        predicates.add(qb.equal(modelo.get(Modelo_.categoria), categoria));
        Expression<String> nombre = categoria.get(Categoria_.nombre);
        cq.multiselect(nombre.alias("prod"), sum.alias("suma"));
        cq.where(predicates.toArray(new Predicate[]{}));
        cq.groupBy(categoria.get(Categoria_.nombre));

        return getEntityManager().createQuery(cq).getResultList();
    }

Espero que le sirva a alguien,
Saludos

0voto

Peter comentado

Gracias por compartir la solución!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta