SQL语法异常:无法准备语句

huangapple go评论170阅读模式
英文:

SQLGrammarException: could not prepare statement

问题

  1. 我有一个使用Spring Boot的应用程序,其中使用CrudRepository访问h2数据库。
  2. public interface PetRepository extends CrudRepository<PetBE, Long> {
  3. @Query("SELECT p FROM PetBE p INNER JOIN TagBE t WHERE t.name IN :tags")
  4. public List<PetBE> findPetsByAnyTag(@Param("tags") List<String> tags);
  5. }
  6. 我的实体类如下:
  7. @Data
  8. @NoArgsConstructor
  9. @RequiredArgsConstructor
  10. @AllArgsConstructor
  11. @Entity
  12. @Table(name = "pets")
  13. public class PetBE {
  14. @Id
  15. private long id;
  16. @NonNull
  17. private String name;
  18. @ManyToOne(cascade = CascadeType.ALL)
  19. @JoinColumn(name = "category_id", referencedColumnName = "id")
  20. private CategoryBE category;
  21. @NonNull
  22. @ElementCollection
  23. private List<String> photoUrls;
  24. @ManyToMany(cascade = CascadeType.ALL)
  25. @JoinTable(
  26. name = "pet_tags",
  27. joinColumns = @JoinColumn(name = "pet_id"),
  28. inverseJoinColumns = @JoinColumn(name = "tag_id"))
  29. @OrderColumn(name = "id")
  30. private List<TagBE> tags;
  31. @Enumerated(EnumType.STRING)
  32. private StatusEnum status;
  33. }
  34. @Data
  35. @NoArgsConstructor
  36. @RequiredArgsConstructor
  37. @Entity
  38. @Table(name = "tags")
  39. public class TagBE {
  40. @Id
  41. @NonNull
  42. private long id;
  43. @NonNull
  44. private String name;
  45. @ManyToMany
  46. private List<PetBE> pets;
  47. }
  48. 但是当我调用我的方法时,我收到以下错误:
  49. 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
  50. 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:
  51. 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]
  52. 我不知道接下来该怎么办,语法看起来对我来说没问题。
  53. 而且查询在编译时是可以通过的,错误只在运行时出现。
  54. 我在这里漏掉了什么?
英文:

I have a spring boot application with an h2 database that is addressed by a CrudRepository.

  1. public interface PetRepository extends CrudRepository&lt;PetBE, Long&gt; {
  2. @Query(&quot;SELECT p FROM PetBE p INNER JOIN TagBE t WHERE t.name IN :tags&quot;)
  3. public List&lt;PetBE&gt; findPetsByAnyTag(@Param(&quot;tags&quot;) List&lt;String&gt; tags);
  4. }

My Entities are as follows

  1. @Data
  2. @NoArgsConstructor
  3. @RequiredArgsConstructor
  4. @AllArgsConstructor
  5. @Entity
  6. @Table(name = &quot;pets&quot;)
  7. public class PetBE {
  8. @Id
  9. private long id;
  10. @NonNull
  11. private String name;
  12. @ManyToOne(cascade = CascadeType.ALL)
  13. @JoinColumn(name = &quot;category_id&quot;, referencedColumnName = &quot;id&quot;)
  14. private CategoryBE category;
  15. @NonNull
  16. @ElementCollection
  17. private List&lt;String&gt; photoUrls;
  18. @ManyToMany(cascade = CascadeType.ALL)
  19. @JoinTable(
  20. name = &quot;pet_tags&quot;,
  21. joinColumns = @JoinColumn(name = &quot;pet_id&quot;),
  22. inverseJoinColumns = @JoinColumn(name = &quot;tag_id&quot;))
  23. @OrderColumn(name = &quot;id&quot;)
  24. private List&lt;TagBE&gt; tags;
  25. @Enumerated(EnumType.STRING)
  26. private StatusEnum status;
  27. }
  1. @Data
  2. @NoArgsConstructor
  3. @RequiredArgsConstructor
  4. @Entity
  5. @Table(name = &quot;tags&quot;)
  6. public class TagBE {
  7. @Id
  8. @NonNull
  9. private long id;
  10. @NonNull
  11. private String name;
  12. @ManyToMany
  13. private List&lt;PetBE&gt; pets;
  14. }

But when I call my method I get:

  1. 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
  2. Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement &quot;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 (?)&quot;; expected &quot;NOT, EXISTS, INTERSECTS, UNIQUE&quot;; SQL statement:
  3. 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]

I don't know where to go from here the grammar looks fine to me.
Also the query does compile, the error comes only at runtime.
What am I missing here?

答案1

得分: 3

通过不使用定义好的关联,你引入了交叉连接(但是期望是内连接)。你可以在生成的查询片段中看到:

  1. 内连接 tags tagbe1_ on where tagbe1_.name in (?)
  2. ^

你可以通过使用第二个实体作为第一个实体的字段来修复这个问题:

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

By not using the defined relationship you're introducing the cross join (but inner join is expected). You can see it in the following fragment of the generated query:

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

You can fix this by using the second entity as the field of the first one:

  1. @Query(&quot;SELECT p FROM PetBE p INNER JOIN p.tags t WHERE t.name IN :tags&quot;)
  2. public List&lt;PetBE&gt; findPetsByAnyTag(@Param(&quot;tags&quot;) List&lt;String&gt; tags);

huangapple
  • 本文由 发表于 2020年10月19日 08:09:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/64419548.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定