Spring Data Jpa项目使用ManyToMany关系时生成查询语句

7

我有以下实体映射:

@Entity
@Table(name = "books")
public class Book implements Serializable {
    @ManyToMany
    @JoinTable(name="books2categories",
    joinColumns=@JoinColumn(name="book_id"),
    inverseJoinColumns=@JoinColumn(name="category_id"))
    Collection<Category> categories;

...

@Entity
@Table(name = "categories")
public class Category implements Serializable {
    @ManyToMany(mappedBy="categories")
    private Collection<Book> books;

BookRepository接口如下:

public interface BookRepository extends JpaRepository<Book, Long> {

    @Query("SELECT b FROM Book b INNER JOIN b.categories c WHERE c IN (:categories)")
    List<Book> findByCategories(Collection<Category> categories);

如果我的查询本身不正确,请帮我修复。 当我运行findByCategories方法的测试时,出现以下错误:

testFindByCategories(com.savdev.springmvcexample.repository.JpaBookRepositoryTest): org.hibernate.QueryParameterException: 位置超出了声明序数参数的数量。请记住,序数参数是以1为基础的!位置:1;嵌套异常为 java.lang.IllegalArgumentException: org.hibernate.QueryParameterException: 位置超出了声明序数参数的数量。请记住,序数参数是以1为基础的!位置:1

有什么解决方法吗?
第二个问题,我可以调试Spring Data JPA逻辑来传递参数到查询中吗? Spring Data JPA返回了一个代理,我无法确定在哪里使用断点调试此行为。
更新: 我通过使用(?1)修复了它。
@Query("SELECT b FROM Book b INNER JOIN b.categories c WHERE c IN (?1)")

代替
@Query("SELECT b FROM Book b INNER JOIN b.categories c WHERE c IN (:categories)")
2个回答

18

由于参数名称在字节码中丢失,您需要使用@Param注释来指示将其映射为JPQL中:category变量的参数。因此,您的代码应如下所示:

@Query("SELECT b FROM Book b INNER JOIN b.categories c WHERE c IN (:categories)")
List<Book> findByCategories(@Param("categories") Collection<Category> categories);

?1 肯定可行,但可能不够易读。


0
你可以直接使用JPA命名规则来解决这个问题。 List<Book> findAllByCategoriesIn(Collection<Category> categories); 希望它能帮助解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接