Comment définir une requête de dépôt JPA avec une jointure

j'aimerais faire une requête de jointure en utilisant le dépôt Jpa avec 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é Hibernante de Table Utilisateur et zone

alors j'ai 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 L'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;
    }       
}
27
demandé sur lloiacono 2012-10-31 13:29:03

1 réponses

vous éprouvez 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.

lors de l'exécution d'une jointure en JPQL, vous devez vous assurer qu'une association sous-jacente existe entre les entités qui tentent d'être jointées. Dans votre exemple, il manque une association entre les entités Utilisateur et zone. Afin de créer cette association nous devons ajouter un champ de zone dans la classe D'Utilisateur et établir la cartographie appropriée JPA. J'ai joint la source pour l'Utilisateur ci-dessous. (Veuillez noter que j'ai déplacé les mappages de champs)

de l'Utilisateur.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 faire référence à l'objet area dans votre déclaration @Query. La requête spécifiée dans votre annotation @Query doit suivre la bonne syntaxe, ce qui signifie que vous devez omettre la clause on. Voir la suivantes:

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

en regardant votre question j'ai aussi fait la relation entre L'utilisateur et les entités de zone bidirectionnelle. Voici la source pour l'entité de zone pour établir la relation bidirectionnelle.

Zone.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;
    }
}
41
répondu Kevin Bowersox 2012-10-31 15:09:37