web-dev-qa-db-fra.com

Comment définir une requête de référentiel JPA avec une jointure

Je souhaite créer une requête de jointure à l'aide du référentiel Jpa avec l'annotation @Query.

J'ai deux tables:

 table user 
 with iduser,user_name 

et:

 table area 
 with idarea, area_name and iduser

La requête native est:

 SELECT
 u.user_name 
 FROM
  user as u 
  INNER JOIN area as a ON a.iduser = u.iduser
  WHERE
  a.idarea = 4

Maintenant, j'ai une entité Table Hibernate Utilisateur et Zone

J'ai donc essayé avec UserRespository

@Query(SELECT  u.userName FROM  User u 
  INNER JOIN Area a ON a.idUser = u.idUser
  WHERE
  a.idArea = :idArea)
List<User> findByIdarea(@Param("idArea") Long idArea);

Le journal dit:

jeton inattendu:

Une idée, s'il vous plaît?

Ma table entité

#User Table
@Entity
@Table(name="user")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long idUser;
    private String userName;

    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="iduser")
    public Long getIdUser() {
        return idUser;
    }

    public void setIdUser(Long idUser) {
        this.idUser = idUser;
    }

    @Column(name="user_name")
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

#AREA table

@Entity
@Table(name="area")
public class Area  implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long idArea;
    private String areaName;
    private Long idUser;

    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="idarea")
    public Long getIdArea() {
        return idArea;
    }

    public void setIdArea(Long idArea) {
        this.idArea = idArea;
    }

    @Column(name="area_name")
    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }

    @Column(name="iduser")
    public Long getIdUser() {
        return idUser;
    }

    public void setIdUser(Long idUser) {
        this.idUser = idUser;
    }       
}
35
Shinigami

Vous rencontrez ce problème pour deux raisons.

  • La requête JPQL n'est pas valide.
  • Vous n'avez pas créé d'association entre vos entités que la requête JPQL sous-jacente peut utiliser.

Lorsque vous effectuez une jointure dans JPQL, vous devez vous assurer qu'il existe une association sous-jacente entre les entités qui tentent de se joindre. Dans votre exemple, il vous manque une association entre les entités Utilisateur et Zone. Afin de créer cette association, nous devons ajouter un champ Zone dans la classe User et établir le mappage JPA approprié. J'ai joint le source pour l'utilisateur ci-dessous. (Veuillez noter que j'ai déplacé les correspondances vers les champs)

ser.Java

@Entity
@Table(name="user")
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="iduser")
    private Long idUser;

    @Column(name="user_name")
    private String userName;

    @OneToOne()
    @JoinColumn(name="idarea")
    private Area area;

    public Long getIdUser() {
        return idUser;
    }

    public void setIdUser(Long idUser) {
        this.idUser = idUser;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Area getArea() {
        return area;
    }

    public void setArea(Area area) {
        this.area = area;
    }
}

Une fois cette relation établie, vous pouvez référencer l’objet area dans votre déclaration @Query. La requête spécifiée dans votre annotation @Query doit respecter la syntaxe appropriée, ce qui signifie que vous devez omettre la clause on. Voir ce qui suit:

@Query("select u.userName from User u inner join u.area ar where ar.idArea = :idArea")

En examinant votre question, j'ai également rendu la relation bidirectionnelle entre les entités Utilisateur et Zone. Voici la source de l'entité Area pour établir la relation bidirectionnelle.

Area.Java

@Entity
@Table(name = "area")
public class Area {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="idarea")
    private Long idArea;

    @Column(name="area_name")
    private String areaName;

    @OneToOne(fetch=FetchType.LAZY, mappedBy="area")
    private User user;

    public Long getIdArea() {
        return idArea;
    }

    public void setIdArea(Long idArea) {
        this.idArea = idArea;
    }

    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}
57
Kevin Bowersox