Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Define a JPA Repository Query with a Join

I would like to make a Join query using Jpa repository with annotation @Query.

I have two tables:

 table user   with iduser,user_name  

and:

 table area   with idarea, area_name and iduser 

The native query is:

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

Now I have a Table Hibernate entity User and Area

So I tried with 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); 

The Log says:

unexpected token:

Any Idea, please?

My table Entity

#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;     }        } 
like image 886
Shinigami Avatar asked Oct 31 '12 09:10

Shinigami


People also ask

What is join in JPA?

First of all, JPA only creates an implicit inner join when we specify a path expression. For example, when we want to select only the Employees that have a Department, and we don't use a path expression like e. department, we should use the JOIN keyword in our query.

How can I join JPA specification?

Joining Tables with JPA Specifications select author0_.id as id1_1_, author0_. first_name as first_na2_1_, author0_. last_name as last_nam3_1_ from author author0_ inner join author_books books1_ on author0_.id = books1_. author_id inner join book book2_ on books1_.

How do you join two tables in spring?

Here is an attempt: @Entity @Table(name = "Release_date_type") public class ReleaseDateType { @Id @GeneratedValue(strategy=GenerationType. TABLE) private Integer release_date_type_id; // ... @Column(nullable = true) private Integer media_Id; // with getters and setters... }


Video Answer


1 Answers

You are experiencing this issue for two reasons.

  • The JPQL Query is not valid.
  • You have not created an association between your entities that the underlying JPQL query can utilize.

When performing a join in JPQL you must ensure that an underlying association between the entities attempting to be joined exists. In your example, you are missing an association between the User and Area entities. In order to create this association we must add an Area field within the User class and establish the appropriate JPA Mapping. I have attached the source for User below. (Please note I moved the mappings to the fields)

User.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;     } } 

Once this relationship is established you can reference the area object in your @Query declaration. The query specified in your @Query annotation must follow proper syntax, which means you should omit the on clause. See the following:

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

While looking over your question I also made the relationship between the User and Area entities bidirectional. Here is the source for the Area entity to establish the bidirectional relationship.

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;     } } 
like image 105
Kevin Bowersox Avatar answered Oct 11 '22 16:10

Kevin Bowersox