简体   繁体   中英

How to create a TypedQuery in JPQL that queries two tables using an implicit join?

I'm trying to learn how to use implicit joins in JPQL. An example I'm working from seems to suggest that one can reference a foreign key as a path and then have access to attributes in the table the foreign key references.

It's a 1:M mandatory relationship between User and Report. userId is the foreign key that references User.

I've checked that I have the right libraries imported that I have the right mapping (@JoinColumn, @ManyToOne, @OneToMany, mappedBy, etc), everything seems to be okay.

@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();
}

As seen above I'm trying to access the "height" attribute in the "User" table with: r.UserId.height

Based on the example I'm working from I'd expect the join to work here however the result I'm getting is this error: "The state field path 'r.userId.height' cannot be resolved to a valid type."

Am I missing something here? Any feedback is much appreciated.

Update to show mapping:

In report 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;

In user 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;

The problem is this part:

r.userId.height

In order for this to work, userId must be an entity. You can define a relationship with user field in Report and write something like:

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

Edit - change this:

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

into:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM