SQLGrammarException:无法准备语句

Posted

技术标签:

【中文标题】SQLGrammarException:无法准备语句【英文标题】:SQLGrammarException: could not prepare statement 【发布时间】:2021-02-01 18:28:23 【问题描述】:

我有一个带有一个由 CrudRepository 寻址的 h2 数据库的 Spring Boot 应用程序。

public interface PetRepository extends CrudRepository<PetBE, Long> 

    @Query("SELECT p FROM PetBE p INNER JOIN TagBE t WHERE t.name IN :tags")
    public List<PetBE> findPetsByAnyTag(@Param("tags") List<String> tags);

我的实体如下

@Data
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "pets")
public class PetBE 
    
    @Id
    private long id;

    @NonNull
    private String name;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "category_id", referencedColumnName = "id")
    private CategoryBE category;
    
    @NonNull
    @ElementCollection
    private List<String> photoUrls;
    
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
        name = "pet_tags", 
        joinColumns = @JoinColumn(name = "pet_id"), 
        inverseJoinColumns = @JoinColumn(name = "tag_id"))
    @OrderColumn(name = "id")
    private List<TagBE> tags;
    
    @Enumerated(EnumType.STRING)
    private StatusEnum status;



@Data
@NoArgsConstructor
@RequiredArgsConstructor
@Entity
@Table(name = "tags")
public class TagBE 

    @Id
    @NonNull
    private long id;
    
    @NonNull
    private String name;
    
    @ManyToMany
    private List<PetBE> pets;
    


但是当我调用我的方法时,我得到:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [select petbe0_.id as id1_4_, petbe0_.category_id as category4_4_, petbe0_.name as name2_4_, petbe0_.status as status3_4_ from pets petbe0_ inner join tags tagbe1_ on where tagbe1_.name in (?)]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "SELECT PETBE0_.ID AS ID1_4_, PETBE0_.CATEGORY_ID AS CATEGORY4_4_, PETBE0_.NAME AS NAME2_4_, PETBE0_.STATUS AS STATUS3_4_ FROM PETS PETBE0_ INNER JOIN TAGS TAGBE1_ ON WHERE[*] TAGBE1_.NAME IN (?)"; expected "NOT, EXISTS, INTERSECTS, UNIQUE"; SQL statement:
select petbe0_.id as id1_4_, petbe0_.category_id as category4_4_, petbe0_.name as name2_4_, petbe0_.status as status3_4_ from pets petbe0_ inner join tags tagbe1_ on where tagbe1_.name in (?) [42001-200]

我不知道从哪里开始,语法对我来说很好。 查询也会编译,错误仅在运行时出现。 我在这里错过了什么?

【问题讨论】:

logicbig.com/tutorials/java-ee-tutorial/jpa/… 【参考方案1】:

通过不使用定义的关系,您将引入交叉连接(但需要内部连接)。您可以在生成的查询的以下片段中看到它:

inner join tags tagbe1_ on where tagbe1_.name in (?)
                           ^

您可以通过使用第二个实体作为第一个实体的字段来解决此问题:

@Query("SELECT p FROM PetBE p INNER JOIN p.tags t WHERE t.name IN :tags")
public List<PetBE> findPetsByAnyTag(@Param("tags") List<String> tags);

【讨论】:

以上是关于SQLGrammarException:无法准备语句的主要内容,如果未能解决你的问题,请参考以下文章

SQLGrammarException:无法执行查询:找不到列?

org.hibernate.exception.SQLGrammarException:无法提取 ResultSet

无法打开 JPA EntityManager 进行事务处理;嵌套异常是 org.hibernate.exception.SQLGrammarException:无法获取 JDBC 连接

org.hibernate.exception.SQLGrammarException: could not execute query

Hibernate - OneToMany 单向映射 - SQLGrammarException

SQLGrammarException: could not extract ResultSet