Search code examples
javajpajpa-2.0criteria

JPA 2.0 CriteriaBuilder : SELECT FROM … IN


I want to create the following SQL query using JPA 2.0 CriteriaBuilder :

SELECT * FROM PROFIL WHERE PROFILID IN (SELECT PROFILID FROM ROLEPROFIL WHERE ROLEID = roleId)

Here are my classes :

Profil :

public class Profil extends AbstractDomain<Long> {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idgen_x")
    @UiInfo(name = "Identifiant")
    private Long profilId;

    @Column(nullable = false)
    @UiInfo(name = "Libellé")
    private String lib;

}

Role :

public class Role extends AbstractDomain<Long> {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idgen_x")
    @UiInfo(name = "Identifiant")
    private Long roleId;
}

RoleProfil :

public class RoleProfil extends AbstractDomain<Long> {
    @Id
    @Column
    @UiInfo(name = "Identifiant")
    private Long roleProfilId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(nullable = false)
    @UiInfo(name = "Profil")
    private Profil profilId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(nullable = false)
    @UiInfo(name = "Rôle")
    private Role roleId;

}

What I want to do is to create a function that will get Profils by a Role ID, using JPA.

This is what I started, but I'm new to JPA and I couldn't figure out how to do it :

public List<Profil> findProfilsByRoleId(Long roleId) {
        final CriteriaBuilder builder = getCriteriaBuilder();
        final CriteriaQuery<Profil> criteriaQuery = builder.createQuery(Profil.class);
        final Root<Profil> from = criteriaQuery.from(Profil.class);

        //TODO

        TypedQuery<Profil> query = getEntityManager().createQuery(criteriaQuery);
        return query.getResultList();

    }

How can I do that ?


Solution

  • SELECT  PF.* 
    FROM PROFIL AS PF
    INNER JOIN ROLEPROFIL AS RPF
    ON RPF.PROFILID = PF.PROFILID 
    WHERE RPF.ROLEID = {roleId}
    

    Might be a more easy to implement query. I think the code in java could be something like this (I have not tested just proposed solution):

    public List<Profil> findProfilsByRoleId(Long roleId) {
        final CriteriaBuilder builder = getCriteriaBuilder();
        final CriteriaQuery<Profil> query = builder.createQuery(Profil.class);
        final Root<RoleProfil> from = query.from(RoleProfil.class);
    
        query.select(from.get(RoleProfil_.profilId));
        query.where(builder.equal(from.get(RoleProfil_.roleId).get(Role_.roleId), roleId));
    
        final TypedQuery<Profil> typedQuery = getEntityManager().createQuery(query);
        return typedQuery.getResultList();
    
    }