Search code examples
jpajpqlcriteria-apijava-ee-7named-query

Issues with bidirectional OneToMany mapping and NamedQuery


I have two entities connected bidirectional and I want to query the Location and its votes only for a specific date.

Location:

@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;

Vote:

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

  @Basic
  @ManyToOne
  @NotNull
  private User user;

  @Basic
  @ManyToOne
  @NotNull
  private Location location;

I was trying to use the named query but it seems that the Location always contains all votes regardless the condition.
Isn't it possible to map the queried values back to the object?

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

What is wrong?
If it isn't possible with NamedQueries, I also can use the Criteria API.


Solution

  • When you get an entity as a result from some query, you get the whole entity. It is not possible in JPA to get just a subset of all data, trimmed by where condition.

    Well, if you use Hibernate, take a look at Hibernate Filters, with them you could get the result you want.

    Note about your query, you have JOIN l.votes so you don't need to join it again with WHERE v.location = l.