Esto puede parecer básico, pero es tarde y estoy teniendo problemas con el siguiente.

class Group {

  @Id
  String id;
}

class Participation {

  @Id
  String id;

  @ManyToOne
  @JoinColumn(name = "GROUP_ID")
  Group group;

  @ManyToOne
  @JoinColumn(name = "USER_ID")
  User user;
}

class User {

  @Id
  String id;

  @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  Set<Participation> participations;
}

Diagrama de clases

Así

Participación –>1 Grupo de

y el Usuario 1<–>N de la Participación

¿Cómo puedo recuperar todos los Grupos, para un Usuario determinado, los asociados de la Participación (o null es que no hay ninguno)? He estado jugando con la combinación de las recopilaciones, pero fue en vano hasta ahora…

Muchas gracias,

CN

PS. Puedo hacer esto en SQL así :

select g.d, p.id 
from group as g 
left join participation as p 
on p.group_id = g.id and p.user_id = 2;
  • edit: Añadido el diagrama y mejor sql solución…
InformationsquelleAutor ChambreNoire | 2016-09-29

2 Comentarios

  1. 3

    (Probablemente algún error tipográfico en el HQL en sí, sino la idea debe ser la correcta)

    Lo que están pidiendo, basado en SQL y la descripción, es encontrar todos los Participation (y su correspondiente Group) basado en User, que es simplemente

    select p.id, p.group.id from Participation p where p.user.id = :userId

    Para hacerlo mejor, usted debe ir a por las entidades en su lugar:

    from Participation p left join fetch p.group where p.user.id = :userId

    Hubo algunas confusiones en la comprensión de lo que estaba tratando de hacer:
    Desea que todos los grupos (independientemente de su condición). Y, para un determinado usuario, que desea encontrar todos los grupos y de las participaciones que el usuario está involucrado.

    Pesar de que debería ser posible mediante el uso de Derecho-outer-join:

    select g, p from Participation p 
        right outer join p.group g 
        where p.user.id=:userId

    O, en la versión posterior de Hibernate (>= 5.1 ?), se permiten explicitar la combinación (no lo he probado antes, usted puede darle una oportunidad) (Reemplazar with con on si usted está usando JPQL):

    select g, p from Group g
        left outer join Participation p 
            with p.group = g
        left outer join p.user u
        where u.id = :userId

    O usted puede utilizar otras técnicas como la subconsulta etc. Sin embargo prefiero separarlos en las consultas más sencillas en su caso y hacer una simple agregación en el código.

    La idea básica es

    1. De consulta para todos los grupos: from Groups
    2. De consulta para todas las participaciones de un usuario: from Participation p join fetch p.group where p.user.id=:userId

    Entonces usted puede agregar fácilmente a la forma que desee, por ejemplo,Map<Group, List<Participation>>, o incluso más significativos del objeto de valor.

    El beneficio es el acceso a los datos de la consulta es más simple y más reutilizable (esp si se envuelve en DAO/Repositorio método de buscador). Uno más de ida y vuelta a DB no debe causar ninguna obvio impacto en el rendimiento aquí.

    • Gracias, a excepción de que de esta manera no entiendo a los Grupos sin una Participación para el Usuario especificado.
    • No tengo dbms en la mano, pero hacer un left join como su ejemplo con el id de usuario debe todavía sólo se dará con el grupo de participantes ¿no? Y le pidió «que para un usuario dado, el dado de la participación», que dándole participación con el usuario no se contradice con lo que usted pidió. De todos modos, tener una oportunidad para from Participation p left join p.user u where u.id =:userid or u is null
    • Agh, supongo que no he entendido lo que me pediste. Realmente quiere que todos los grupos de la derecha? De todos modos si mal no recuerdo, HQL hacer de soporte para Unir, así que usted puede comenzar con la Participación right join p.grupo?
  2. -1

    Es necesario asignar las participation relación en la Group entidad. Si la relación entre Participation y Group 1..N:

    class Group {
      String id
      List<Participation> participations
    }

    La JPQL puede ser:

    SELECT g.id, p.id FROM Group g
    JOIN g.participations p
    JOIN p.user user
    WHERE user.id = :idUser

    Usted puede recibir esta información como List<Object[]> (Object[0] es el id de grupo y Object[1] es la participación id) o el uso SELECCIONE NUEVO.

    Sin mapa el Grupo/la Participación de relación, que puede hacer:

    SELECT g.id, p.id FROM Group g, Participation p
    JOIN p.user user
    JOIN p.group groupp
    WHERE g.id = groupp.id
    AND user.id = :idUser

    Pero usted no puede hacer un LEFT JOIN el uso de esta estrategia. La consulta sobre comportamientos como un JOIN.

    Es normal que con Hibernate mapa al lado de una relación que le gustaría hacer una consulta. Así que, recomiendo el primer enfoque, el mapeo de la relación.

    • Me temo que la relación entre la Participación y el Grupo no es 1:1 (he añadido un diagrama de la pregunta original).
    • no hay problema! He editado mi pregunta, pero funciona de la misma manera
    • No hay forma de hacerlo sin necesidad de agregar el Grupo>la Participación de la asociación?
    • ver mi respuesta, de nuevo, he editado.
    • Theta unirse es algo que prefiero evitar (esp nueva versión de hibernación permitir arbitraria «en la» cláusula de une ahora). Y la relación de las entidades debe ser lo suficientemente bueno para escribir significativa HQL
    • ¿Qué están ustedes hablando? Él no proporcionar la versión de Hibernación demasiado.
    • Theta estilo de combinación de medios : FROM Group g, Participation p ... WHERE g.id = groupp.id ... . Hay inconvenientes con esto: 1. simplemente no puede hacer lo OP que está pidiendo (outer join) 2. Es difícil de leer.

Dejar respuesta

Please enter your comment!
Please enter your name here