Reputation: 646
I am currently working on a SpringBoot app that allows users to book a table in a specific restaurant. The user can filter the restaurants according to various preferences. One of these are the food types they serve.
The restaurant class has a list of foods as an attribute as seen below.
package entities;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
@Entity(name = "Restaurant")
public class Restaurant extends User{
@Column(name = "name", unique=true, nullable = false)
@NonNull
private String name;
@Column(name = "rut", nullable = false)
@NonNull
private String RUT;
@Column(name = "address")
private String address;
@Column(name = "phone")
private Long phoneNumber;
@Column(name = "max_capacity", nullable = false)
@NonNull
private Integer maxCapacity;
@ManyToOne
@JoinColumn(name = "neighbourhood", nullable = false)
@NonNull
private Neighbourhood neighbourhood;
@ManyToMany(fetch=FetchType.EAGER)
private List<Food> foods = new ArrayList<>();
public Restaurant(String email, String username, String password, String
name, String RUT, Integer maxCapacity, Neighbourhood neighbourhood) {
super(email, username, password);
this.name = name;
this.RUT = RUT;
this.maxCapacity = maxCapacity;
this.neighbourhood = neighbourhood;
}
}
Then, the query I wrote after searching everywhere how to do it is the following:
package labtic.database;
import entities.Food;
import entities.Neighbourhood;
import entities.Restaurant;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface RestaurantRepository extends
JpaRepository<Restaurant,String> {
@Query("SELECT r2 FROM Restaurant r2 WHERE EXISTS (SELECT r, COUNT(r) FROM
Restaurant r INNER JOIN r.foods rf WHERE rf IN :foods AND r2=r GROUP BY r
HAVING COUNT(r)=:size) AND r.name LIKE '%:name%' AND r.neighbourhood IN
:neighbourhoods AND r.maxCapacity >= :maxCapacity")
List<Restaurant> findByFilters(@Param("name") String name, @Param("foods")
List<Food> foods, @Param("neighbourhoods") List<Neighbourhood>
neighbourhoods, @Param("maxCapacity")Integer maxCapacity);
}
The last part of the Stacktrace (the one I think is relevant) is the following:
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid
path: 'r.name' [SELECT r2 FROM entities.Restaurant r2 WHERE EXISTS (SELECT
r, COUNT(r) FROM entities.Restaurant r INNER JOIN r.foods rf WHERE rf IN
:foods AND r2=r GROUP BY r HAVING COUNT(r)=:size) AND r.name LIKE '%:name%'
AND r.neighbourhood IN :neighbourhoods AND r.maxCapacity >= :maxCapacity]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) ~ [hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:272) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
... 78 common frames omitted
If I need to add more information about my code to this question please let me know. It is my first question in Stackoverflow so sorry if I am not making myself clear.
Thanks in advance!
Upvotes: 3
Views: 7179
Reputation: 13506
You need to use r2
instead of r
outside the subquery
@Query("SELECT r2 FROM Restaurant r2
WHERE EXISTS
(SELECT r, COUNT(r) FROM
Restaurant r INNER JOIN r.foods rf WHERE rf IN :foods AND r2=r GROUP BY r
HAVING COUNT(r)=:size)
AND r2.name LIKE '%:name%' AND r2.neighbourhood IN
:neighbourhoods AND r.maxCapacity >= :maxCapacity")
Upvotes: 4