Resolviendo la consulta JPA encontrando la última entrada en la lista conectada

StackOverflow https://stackoverflow.com/questions/442488

  •  22-07-2019
  •  | 
  •  

Pregunta

Se da la siguiente estructura de clase:

class Job 
{
    String description;
    Collection<JobHistory> history;
}

class JobHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Esta estructura de clases es accesible en el db a través de JPA. En la capa DAO puedo escribir consultas en sintaxis JPA.

El problema: quiero una lista con las entradas Job y JobHistory para un propietario determinado con una identificación dada y quién es el último en el Jobhistory del trabajo (ordenado por asignar fecha). Suena bastante complicado, quizás más simple: darme todos los trabajos y JobHistory donde el propietario especificado es el propietario real del trabajo.

Actualización: para mayor claridad, cambiaré ligeramente los nombres de las clases.

class Job 
{
    String description;
    Collection<JobOwnerHistory> history;
}

class JobOwnerHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Cada Job tiene un historial de sus propietarios ordenados por asignar fecha . El propietario real recibió el último trabajo asignado (es decir, MAX (asignar fecha) ). Quiero encontrar para cada trabajo la entrada JobOwnerHistory con MAX (asignar fecha) para un usuario específico User .

¿Fue útil?

Solución

Prueba:

SELECT j, j.history FROM Job j JOIN User u WHERE u.name = :name

Si tuviera que hacer esto en EclipseLink, lo cambiaría ligeramente:

public List<Job> getAllJobsForUser(String username) {
  List<Job> jobs = entityManager
    .createQuery("SELECT j FROM Job j JOIN User u WHERE u.name = :name")
    .setParameter("name", username)
    .setHint(QueryHints.BATCH, "j.history")
    .queryForList();
}

¿La diferencia? En la primera versión, está devolviendo dos objetos, por lo que debe recuperarlos de una lista o matrices de objetos, mientras que en la segunda, la sugerencia de consulta solo carga todos los historiales de trabajo de una relación de uno a muchos (supuestamente) perezosa .

No sé si Hibernate tiene un equivalente a esto. Toplink Essentials no lo hace. Pero es una de mis características favoritas de EclipseLink.

Ah, y obviamente puede (y probablemente debería) usar una consulta con nombre en lugar de una consulta ad hoc como lo he hecho (ya que pueden verificarse durante la compilación).

Otros consejos

Encontré la siguiente respuesta para la consulta:

SELECT j, h FROM Job j JOIN j.history h JOIN h.jobOwner u
WHERE u.name = :name AND 
    (SELECT MAX(h2.assignDate) FROM Job j2 JOIN j2.history h2
     WHERE h2 member of j.history) = h.assignDate

La parte más importante de la consulta es la subselección con MAX(h2.assignDate) porque quiero obtener el trabajo y la entrada más reciente en el historial del propietario .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top