Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generation query when the ManyToMany relationship is used by Spring Data Jpa project

I've the following entities mapping:

@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 interface is looked:

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);

Please fix me if I'm wrong in the query itself. When I run test for the findByCategories method, I'm getting the error:

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

Which option do I have to resolve it?

And the second, can I debug Spring Data Jpa logic that passes the argument into the query? I'm getting a proxy returned by Spring Data Jpa, cannot understand where to use break point to debug this behaviour.

UPDATE: I've fixed it by using (?1):

@Query("SELECT b FROM Book b INNER JOIN b.categories c WHERE c IN (?1)")

instead of

@Query("SELECT b FROM Book b INNER JOIN b.categories c WHERE c IN (:categories)")
like image 752
Alexandr Avatar asked Nov 10 '13 06:11

Alexandr


People also ask

How do you create a many-to-many relationship in spring boot JPA?

Implementation in JPA. Modeling a many-to-many relationship with POJOs is easy. We should include a Collection in both classes, which contains the elements of the others. After that, we need to mark the class with @Entity and the primary key with @Id to make them proper JPA entities.

How fetch data in many-to-many relationship in JPA?

@ManyToMany Annotation provides the facility to relate data many-to-many to database table. In this case, you need to insert, update and retrieve many data to many tables. To use java.

What is many-to-many relationship JPA?

The Many-To-Many mapping represents a collection-valued association where any number of entities can be associated with a collection of other entities. In relational database any number of rows of one entity can be referred to any number of rows of another entity.


1 Answers

Since parameter names are lost in bytecode, you need to use @Param annotation to indicate the parameter that is mapped as the :category variable in your JPQL. So, you code would look like:

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

?1 certainly works, but is probably not as readable.

like image 111
wasabi Avatar answered Oct 10 '22 19:10

wasabi