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)")
4

2 回答 2

18

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

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

?1当然有效,但可能不那么可读。

于 2013-11-10T20:46:09.080 回答
0

您可以直接使用 JPA 命名约定来解决该问题。

List<Book> findAllByCategoriesIn(Collection<Category> categories);

希望它有助于解决问题。

于 2021-02-21T14:36:40.437 回答