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)")
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.
@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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With