存在的 JPQL 子查询
JPQL subquery with exists
我目前正在开发一个 SpringBoot 应用程序,它允许用户在特定餐厅预订 table。用户可以根据各种喜好筛选餐厅。其中之一是他们提供的食物类型。
餐厅 class 有一个食物列表作为属性,如下所示。
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;
}
}
然后,我到处搜索如何做后写的查询如下:
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);
}
Stacktrace 的最后一部分(我认为相关的部分)如下:
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
如果我需要在此问题中添加有关我的代码的更多信息,请告诉我。这是我在 Whosebug 中的第一个问题,很抱歉,如果我没有说清楚。
提前致谢!
您需要在子查询外使用 r2
而不是 r
@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")
我目前正在开发一个 SpringBoot 应用程序,它允许用户在特定餐厅预订 table。用户可以根据各种喜好筛选餐厅。其中之一是他们提供的食物类型。
餐厅 class 有一个食物列表作为属性,如下所示。
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;
}
}
然后,我到处搜索如何做后写的查询如下:
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);
}
Stacktrace 的最后一部分(我认为相关的部分)如下:
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
如果我需要在此问题中添加有关我的代码的更多信息,请告诉我。这是我在 Whosebug 中的第一个问题,很抱歉,如果我没有说清楚。
提前致谢!
您需要在子查询外使用 r2
而不是 r
@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")