【问题标题】:How To Define a JPA Repository Query with a Join如何使用连接定义 JPA 存储库查询
【发布时间】:2012-10-20 17:26:20
【问题描述】:

我想使用带有注释 @Query 的 Jpa 存储库进行 Join 查询。

我有两张桌子:

 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

现在我有一个 Table 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;
    }       
}

【问题讨论】:

    标签: java jpa orm repository jpql


    【解决方案1】:

    您遇到此问题有两个原因。

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

    在 JPQL 中执行连接时,您必须确保尝试连接的实体之间存在底层关联。在您的示例中,您缺少 User 和 Area 实体之间的关联。为了创建这种关联,我们必须在 User 类中添加一个 Area 字段并建立适当的 JPA 映射。我在下面附上了用户的来源。 (请注意我已将映射移至字段)

    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")
    

    在查看您的问题时,我还将 User 和 Area 实体之间的关系设为双向。这里是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;
        }
    }
    

    【讨论】:

    • 发布您的实体,您需要确保它们已关联
    • @Shinigami 解决了你的问题吗?
    • 好的,现在我建立了关联并且没有错误,Tnx,但现在查询是?......
    • 好像没有找到表...也许我必须声明一个(区域)表?
    • 引起:org.hibernate.hql.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:396) 处的 java.lang.NullPointerException
    猜你喜欢
    • 1970-01-01
    • 2021-04-06
    • 2016-03-13
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    相关资源
    最近更新 更多