存在的 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")