双向 OneToMany 映射和 NamedQuery 的问题

Issues with bidirectional OneToMany mapping and NamedQuery

我有两个双向连接的实体,我只想查询特定日期的位置及其投票。

地点:

@Entity
@Table(name = "TAB_LOCATION")
@NamedQueries({
    @NamedQuery(name = "Location.getVotedLocations", query = "SELECT l FROM Location l JOIN l.votes v WHERE v.location = l AND DATE(v.createdAt) = DATE(:date) ORDER BY l.name")
})
public class Location extends AbstractEntity {

  @Basic
  @Size(min = 5, max = 50)
  private String name;

  @Basic
  @Size(min = 0, max = 50)
  private String address;

  @OneToMany(mappedBy = "location")
  private Set<Vote> votes;

  @Basic
  private String description;

投票:

@Entity
@Table(name = "TAB_VOTE")
public class Vote extends AbstractEntity {

  @Basic
  @ManyToOne
  @NotNull
  private User user;

  @Basic
  @ManyToOne
  @NotNull
  private Location location;

我试图使用命名查询,但无论条件如何,Location 似乎总是包含所有投票。
不是可以将查询到的值映射回对象吗?

entityManager.createNamedQuery("Location.getVotedLocations").
  setParameter("date", date).getResultList();

怎么了?
如果无法使用 NamedQueries,我也可以使用 Criteria API.

当您从某个查询中得到一个实体时,您就得到了整个实体。在 JPA 中不可能只获取所有数据的一个子集,并根据 where 条件进行修剪。

好吧,如果你使用 Hibernate,看看 Hibernate Filters,用它们你可以得到你想要的结果。

请注意您的查询,您有 JOIN l.votes,因此您不需要使用 WHERE v.location = l 再次加入它。

这是一个简单的 MySql 声明,它将 return locationIDs 而不是 Location 在特定日期投票的实体。

 Select DISTINCT LocationID FROM VOTE WHERE DATE == dateCreated;

然后您可以通过 LocationID 获得 Location 实体。