如何在 JPQL 中创建使用隐式连接查询两个表的 TypedQuery?
How to create a TypedQuery in JPQL that queries two tables using an implicit join?
我正在尝试学习如何在 JPQL 中使用隐式联接。我正在使用的一个示例似乎表明可以将外键引用为路径,然后可以访问 table 外键引用中的属性。
User 和 Report 之间是 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();
}
如上所示,我正在尝试访问 "User" table 中的 "height" 属性:r.UserId.height
基于我正在工作的例子,我希望连接在这里工作但是我得到的结果是这个错误:"The state field path 'r.userId.height' cannot be resolved to a valid type."
我是不是漏掉了什么?非常感谢任何反馈。
显示映射的更新:
在报告中 class:
@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;
在用户 class:
@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;
问题出在这部分:
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;
我正在尝试学习如何在 JPQL 中使用隐式联接。我正在使用的一个示例似乎表明可以将外键引用为路径,然后可以访问 table 外键引用中的属性。
User 和 Report 之间是 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();
}
如上所示,我正在尝试访问 "User" table 中的 "height" 属性:r.UserId.height
基于我正在工作的例子,我希望连接在这里工作但是我得到的结果是这个错误:"The state field path 'r.userId.height' cannot be resolved to a valid type."
我是不是漏掉了什么?非常感谢任何反馈。
显示映射的更新:
在报告中 class:
@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;
在用户 class:
@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;
问题出在这部分:
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;