2012-10-31 29 views
22

我想使用带注释@Query的Jpa存储库进行连接查询。如何使用连接定义JPA存储库查询

我有两个表:

table user 
with iduser,user_name 

和:

table area 
with idarea, area_name and iduser 

本机查询:

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

现在我有一个表的Hibernate实体 用户和区域

所以我试着用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); 

日志说:

意外的标记:

什么想法,请?

我的表实体

#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; 
    }  
} 

回答

34

遇到了两方面的原因这个问题。

  • JPQL查询无效。
  • 您尚未在您的实体之间创建基础JPQL查询可以使用的关联。

当在JPQL中执行连接时,您必须确保尝试连接的实体之间存在底层关联。在你的例子中,你缺少用户和区域实体之间的关联。为了创建这种关联,我们必须在User类中添加一个Area字段并建立适当的JPA映射。我在下面附加了User的源代码。 (请注意,我搬到映射到田间地头)

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

一旦这种关系建立你可以引用区域目标在@Query声明。在@Query注释中指定的查询必须遵循适当的语法,这意味着您应该省略on子句。参见以下内容:

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

在查看您的问题时,我还将用户和区域实体之间的关系设为双向。这是Area实体建立双向关系的来源。

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; 
    } 
} 
+1

对不起......我犯了一个错误,现在我修正后... – Shinigami

+1

安置自己的实体,你需要确保你有他们相关 –

+1

好吧,我didn t make association – Shinigami