【问题标题】:How to create a TypedQuery in JPQL that queries two tables using an implicit join?如何在 JPQL 中创建使用隐式连接查询两个表的 TypedQuery?
【发布时间】:2019-03-24 14:13:50
【问题描述】:

我正在尝试学习如何在 JPQL 中使用隐式连接。我正在使用的一个示例似乎表明可以将外键作为路径引用,然后可以访问外键引用的表中的属性。

这是用户和报告之间的 1:M 强制关系。 userId 是引用 User 的外键。

我检查了我是否导入了正确的库,我有正确的映射(@JoinColumn、@ManyToOne、@OneToMany、mappedBy 等),一切似乎都正常。

@GET
@Path("findByTotalCalBurnedAndHeight/{height}/{totalCalBurned}")
@Produces({"application/json"})
public List<Report> findByTotalCalBurnedAndHeight(@PathParam("height") Integer height, @PathParam("totalCalBurned") Integer totalCalBurned) {
    TypedQuery<Report> q = em.createQuery("SELECT r FROM Report r WHERE r.totalCalBurned = :totalCalBurned AND r.userId.height = :height", Report.class);
    q.setParameter("height", height);
    q.setParameter("totalCalBurned", totalCalBurned);
    return q.getResultList();
}

如上所示,我正在尝试使用以下命令访问“用户”表中的“高度”属性:r.UserId.height

根据我正在使用的示例,我希望连接可以在这里工作,但是我得到的结果是这个错误:“状态字段路径 'r.userId.height' 无法解析为有效类型。”

我在这里遗漏了什么吗?非常感谢任何反馈。

更新以显示映射:

在报告类中:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "REPORT_ID")
private Integer reportId;

@JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")
@ManyToOne(optional = false)
@Basic(optional = false)
@NotNull
@Column(name = "USER_ID")
private Integer userId;

在用户类中:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "USER_ID")
private Integer userId;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")

@Basic(optional = false)
@NotNull
@Column(name = "HEIGHT")
private int height;

【问题讨论】:

    标签: java rest jpa jpql derby


    【解决方案1】:

    问题出在这部分:

    r.userId.height
    

    为了使其工作,userId 必须是一个实体。您可以在Report 中定义与user 字段的关系并编写如下内容:

    "SELECT r FROM Report r left join r.user u WHERE r.totalCalBurned = :totalCalBurned AND u.height = :height"
    

    编辑 - 改变这个:

    @JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")
    @ManyToOne(optional = false)
    @Basic(optional = false)
    @NotNull
    @Column(name = "USER_ID")
    private Integer userId;
    

    进入:

    @JoinColumn(name = "USER_ID")
    @ManyToOne(optional = false)
    @Basic(optional = false)
    @NotNull
    private User user;
    

    【讨论】:

    • 这仍然被认为是隐式连接吗?我的理解是,如果我使用“join”关键字,那么它不再被视为隐式连接。
    • @Pocky 这有什么改变吗?此外我认为left join r.user u 可以省略,但我不确定。
    • 当我尝试您的示例时,出现以下错误:集合值路径 'r.User' 无法解析为有效的关联字段。 [94, 102] 状态字段路径“a.height”无法解析为有效类型。
    • 您是否定义了字段user 与我的回答中的关系?
    • 哦,是的,现在我有 15 个声望,我现在可以点赞,点赞!
    猜你喜欢
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2014-07-13
    • 2014-08-22
    • 2014-01-29
    • 1970-01-01
    相关资源
    最近更新 更多