I'm trying to configure out hql for many-to-one relationship and facing next issue: spring data doesn't select restaurant if votes count for today is less than 1. In database everything's ok
Result should be
{
"id": 3,
"name": "Kroger",
"votes": 2
},
{
"id": 2,
"name": "Fridays",
"votes": 1
},
{
"id": 4,
"name": "Wingstop",
"votes": 1
},
{
"id": 1,
"name": "Macdonalds",
"votes": 0
}
But it is
{
"id": 3,
"name": "Kroger",
"votes": 2
},
{
"id": 2,
"name": "Fridays",
"votes": 1
},
{
"id": 4,
"name": "Wingstop",
"votes": 1
}
Restaurant entity
@Entity
@NoArgsConstructor
@Getter
@Setter
@Table(name = "restaurant", uniqueConstraints = @UniqueConstraint(columnNames = "name"))
public class Restaurant extends NamedEntity {
@OneToMany(mappedBy = "restaurant", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonManagedReference
private Set<Vote> votes;
public Restaurant(Integer id, String name) {
this.id = id;
this.name = name;
}
}
Vote entity
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "votes", uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "date"}, name = "unique_user_id_per_date_idx")})
public class Vote extends BaseEntity {
@Column(name = "date")
@CreationTimestamp
private LocalDate date;
@ManyToOne
@JoinColumn(name = "user_id")
@OnDelete(action = OnDeleteAction.CASCADE)
private User user;
@ManyToOne
@JoinColumn(name = "restaurant_id")
@OnDelete(action = OnDeleteAction.CASCADE)
private Restaurant restaurant;
public Vote(Integer id, LocalDate date, User user, Restaurant restaurant) {
super(id);
this.date = date;
this.user = user;
this.restaurant = restaurant;
}
}
Restaurant repository
@Transactional(readOnly = true)
public interface RestaurantRepository extends BaseRepository<Restaurant> {
// @Query("select r from Restaurant r join r.votes v where v.date=current_date")
// @Query("from Restaurant r left join r.votes v where v.date=current_date")
// @Query("select r from Restaurant r join fetch Vote v on v.date=current_date")
// Set<Restaurant> findAllForCurrentDate();
// @Query("from Restaurant r left join fetch r.votes as v on v.date=current_date")
@Query("from Restaurant r left outer join fetch r.votes as v where v.date=current_date")
Set<Restaurant> findAllForCurrentDate();
}
If you need additional info please let me know.
CodePudding user response:
Problem is solved. Solution:
@Entity
@NoArgsConstructor
@Getter
@Setter
@AllArgsConstructor
@Table(name = "restaurant", uniqueConstraints = @UniqueConstraint(columnNames = "name"))
@NamedEntityGraph(name = "graph.Parent.children", attributeNodes = @NamedAttributeNode("votes")) // added this
public class Restaurant extends NamedEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@OneToMany(mappedBy = "restaurant",
fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonManagedReference
private Set<Vote> votes = new HashSet<>();
public Restaurant(Integer id, String name) {
this.id = id;
this.name = name;
}
}
And repo's method
@Query("select distinct r from Restaurant r left join r.votes v on v.date=current_date")
@EntityGraph(value = "graph.Parent.children") // added this
Set<Restaurant> findAllForCurrentDate();