简体   繁体   中英

JPA crud repository query

Im trying to learn Spring and got problem with JPA repository queries I have 2 classes in bidirectional relationships to each other:

public class MovieGenre {
   // other fields

   @ManyToMany(mappedBy = "genres")
   @JsonBackReference
   private Set<Movie> movies = new HashSet<>();
   // ...
}

and

public class Movie {
// id and other fields

   @ManyToMany(fetch = FetchType.EAGER)
   @JoinTable(
           name = "movie_movie_genre",
           joinColumns = @JoinColumn(name = "movie_id"),
           inverseJoinColumns = @JoinColumn(name = "movie_genre_id"))
   @JsonManagedReference
   private Set<MovieGenre> genres = new HashSet<>();

I would like to create controller to be able to get json with all the movies that are in one of the genres. I was trying to get jpa query doing this for me.

public interface MovieRepository extends CrudRepository<Movie, Long> {

   Stream<Movie> getMoviesByGenresIsLike(String genreName);
}

This dosn't work

To give Idead what Im trying to achive this is normal sql query (and it works in h2 console)

SELECT * FROM MOVIE m 
INNER JOIN movie_movie_genre mmg ON m.movie_id = mmg.movie_id
INNER JOIN movie_genre mg ON mmg.movie_genre_id = mg.genre_id
WHERE genre_name = 'action';

I was trying to write custom query like that

@Query(value = "SELECT * FROM MOVIE m \n" +
       "INNER JOIN movie_movie_genre mmg ON m.movie_id = mmg.movie_id\n" +
       "INNER JOIN movie_genre mg ON mmg.movie_genre_id = mg.genre_id\n" +
       "WHERE genre_name = ?1;", nativeQuery = true)
Optional<Movie> getMoviesByGenres(@Param("name") String name);

This all leads to

2019-10-25 17:07:42.405 ERROR 831 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]
    : Servlet.service() for servlet [dispatcherServlet] in context with path [] 
threw exception [Request processing failed; 
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: 
JPA-style positional param was not an integral ordinal; 
nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: 
JPA-style positional param was not an integral ordinal] with root cause
  • Is there any way I can get list of movies by genre?
  • How to write correct custom query if jpa query is not possible?

  • EDIT: -- I changed query to "SELECT m FROM Movie m INNER JOIN m.genres g WHERE g.genreName =?1" (as suggested in answers below) -- Another problem was lack of @Transactional annotation in controller.

Try switching from using native query to jpql notion:

"SELECT m FROM Movie m INNER JOIN m.genres g WHERE g.genreName = ?1"

Or you can create a MovieGenreRepository and nave a method like:

Stream<MovieGenre> findByGenreNameLike(String genreName);

First of all you must map your entities well and if the names of the fields are exactly the same as your SQL query then it would be something like this:

@Repository
public interface MovieRepository extends CrudRepository<Movie, Long> {

    @Query(value = "SELECT m FROM Movie m INNER JOIN m.genres g ON m.movie_id = g.movie_id WHERE g.genreName = :name")
    Movie getMoviesByGenres(@Param("name") String name);
}

Don't forget to put the @Repository annotation, since we must always follow the hibernate standard.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM