subconsultas query examples criteriabuilder jpa subquery jpa-2.0 criteria-api in-subquery

query - subconsultas en jpa



JPA 2.0, API de criterios, subconsultas, en expresiones (2)

Intenté escribir una declaración de consulta con una subconsulta y una expresión IN muchas veces. Pero nunca he tenido éxito.

Siempre obtengo la excepción, "Error de sintaxis cerca de la palabra clave ''IN''", la instrucción de consulta se compilaba así,

SELECT t0.ID, t0.NAME FROM EMPLOYEE t0 WHERE IN (SELECT ? FROM PROJECT t2, EMPLOYEE t1 WHERE ((t2.NAME = ?) AND (t1.ID = t2.project)))

Sé la palabra antes de ''IN'' perder.

¿Alguna vez has escrito una consulta? ¿Cualquier sugerencia?


A continuación se muestra el pseudocódigo para usar la subconsulta utilizando la API de Criteria.

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery(); Root<EMPLOYEE> from = criteriaQuery.from(EMPLOYEE.class); Path<Object> path = from.get("compare_field"); // field to map with sub-query from.fetch("name"); from.fetch("id"); CriteriaQuery<Object> select = criteriaQuery.select(from); Subquery<PROJECT> subquery = criteriaQuery.subquery(PROJECT.class); Root fromProject = subquery.from(PROJECT.class); subquery.select(fromProject.get("requiredColumnName")); // field to map with main-query subquery.where(criteriaBuilder.and(criteriaBuilder.equal("name",name_value),criteriaBuilder.equal("id",id_value))); select.where(criteriaBuilder.in(path).value(subquery)); TypedQuery<Object> typedQuery = entityManager.createQuery(select); List<Object> resultList = typedQuery.getResultList();

También definitivamente necesita algunas modificaciones ya que he intentado mapearlo de acuerdo con su consulta. Aquí hay un enlace http://www.ibm.com/developerworks/java/library/j-typesafejpa/ que explica muy bien el concepto.


Resurrección tardía.

Su consulta parece muy similar a la de la página 259 del libro Pro JPA 2: Mastering the Java Persistence API , que en JPQL lee:

SELECT e FROM Employee e WHERE e IN (SELECT emp FROM Project p JOIN p.employees emp WHERE p.name = :project)

Utilizando la base de datos EclipseLink + H2, no pude obtener el JPQL del libro ni los criterios respectivos funcionando. Para este problema en particular, he encontrado que si hace referencia al ID directamente en lugar de dejar que el proveedor de persistencia lo resuelva, todo funciona como se espera:

SELECT e FROM Employee e WHERE e.id IN (SELECT emp.id FROM Project p JOIN p.employees emp WHERE p.name = :project)

Finalmente, para responder a su pregunta, aquí hay una consulta de criterios de tipo fuertemente formulados que funciona:

CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Employee> c = cb.createQuery(Employee.class); Root<Employee> emp = c.from(Employee.class); Subquery<Integer> sq = c.subquery(Integer.class); Root<Project> project = sq.from(Project.class); Join<Project, Employee> sqEmp = project.join(Project_.employees); sq.select(sqEmp.get(Employee_.id)).where( cb.equal(project.get(Project_.name), cb.parameter(String.class, "project"))); c.select(emp).where( cb.in(emp.get(Employee_.id)).value(sq)); TypedQuery<Employee> q = em.createQuery(c); q.setParameter("project", projectName); // projectName is a String List<Employee> employees = q.getResultList();