J'ai deux entités User
et Role
. Chaque utilisateur peut avoir plusieurs rôles.
Classe d'utilisateurs
@Override public List<User> getArtists() { return em.createQuery( "from User u, Role r where u.roles='4'", User.class ).getResultList(); }
Classe de rôle:
@Entity public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", updatable = false, nullable = false) private Long id; private String name; }
Ainsi, une nouvelle table jointe est en cours de création appelée: user_role
Je veux créer une requête pour renvoyer une liste d'utilisateurs avec role_id
de 4, par exemple. La requête que j'ai déjà essayée:
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", updatable = false, nullable = false) private Long id; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinTable( name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id") ) private Set<Role> roles = new HashSet<>(); }
Comment puis-je corriger cette requête afin de récupérer une liste d'utilisateurs avec role_id
de 4?
3 Réponses :
Peut-être que vous pouvez consulter le sujet suivant, les réponses données à l'intérieur pointent dans le même sens que votre question: Requête JPA sur une table de jointure
Cela n'est donc possible qu'avec entityManager.createNativeQuery? N'est-ce pas possible avec em.createQuery?
Vous pouvez faire quelque chose comme ceci:
List<User> users = em.createQuery( "select distinct u from User u join fetch u.roles rl where rl.id = :id", User.class) .setHint( QueryHints.HINT_PASS_DISTINCT_THROUGH, false ) .setParameter("id", 1L) .getResultList();
Le QueryHints.HINT_PASS_DISTINCT_THROUGH
est ajouté en tant QueryHints.HINT_PASS_DISTINCT_THROUGH
supplémentaire des performances . Mais veuillez noter que cette optimisation ne fonctionnera qu'avec hibernate 5.2.2.Final ... 5.2.11.Final. Il a été cassé dans le 5.2.12.Final.
Si j'étais vous, j'aurai l'avantage d'utiliser SpringdataJpa avec hibernate et utiliserai simplement cette déclaration: Si vous ne voulez pas utiliser de requête:
public interface UserRepository extends JpaRepository<User, Long> { List<User> findByRoles_Id(Long id); }
Dans votre référentiel d'utilisateurs:
List<User> findByRoles_Id(Long id);
Pour clarifier cela, c'est SpringDataJPA, pas JPA
Merci pour vos commentaires @ACV :)