2013-11-10 4 views
5

Я следующие сущности: отображениезапрос поколения, когда отношения ManyToMany используется проектом Spring Data JPA

@Entity 
@Table(name = "books") 
public class Book implements Serializable { 
    @ManyToMany 
    @JoinTable(name="books2categories", 
    [email protected](name="book_id"), 
    [email protected](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: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 1; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 1

Какой вариант я должен решить это?

А во-вторых, могу ли я отлаживать логику Spring Data Jpa, которая передает аргумент в запрос? Я получаю прокси-сервер, возвращенный Spring Data Jpa, не могу понять, где использовать точку останова для отладки этого поведения.

UPDATE: Я установил его с помощью (?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)") 

ответ

14

Поскольку имена параметров теряются в байткод, вам нужно использовать @Param аннотацию, чтобы указать параметр который отображается как переменная :category в вашем JPQL. Таким образом, вы код будет выглядеть следующим образом:

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

?1 конечно работает, но, вероятно, не читаемые.

Смежные вопросы