JPA Crud репозиторий запрос - PullRequest
       1

JPA Crud репозиторий запрос

1 голос
/ 25 октября 2019

Я пытаюсь изучить Spring и получил проблему с запросами репозитория JPA. У меня есть 2 класса в двунаправленных отношениях друг с другом:

public class MovieGenre {
   // other fields

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

и

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

Я хотел бы создатьконтроллер, чтобы иметь возможность получить JSON со всеми фильмами, которые находятся в одном из жанров. Я пытался получить jpa запрос, делая это для меня.

public interface MovieRepository extends CrudRepository<Movie, Long> {

   Stream<Movie> getMoviesByGenresIsLike(String genreName);
}

Это не работает

Чтобы дать Idead то, что я пытаюсь достичь, это обычный SQL-запрос (и он работает в консоли h2)

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

Я пытался написать собственный запрос, подобный этому

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

Все это приводит к

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
  • Можно ли как-нибудь получить список фильмов по жанрам?
  • Как написать правильный пользовательский запрос, если запрос jpa невозможен?

  • РЕДАКТИРОВАТЬ: - Я изменил запрос на «ВЫБРАТЬ m ИЗ КИНО m ВНУТРЕННЯЯ ПОДПИСКА m.genresg WHERE g.genreName =? 1 "(как предложено в ответах ниже) - Еще одной проблемой было отсутствие аннотации @Transactional в контроллере.

Ответы [ 2 ]

2 голосов
/ 25 октября 2019

Попробуйте перейти от использования нативного запроса к понятию jpql:

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

Или вы можете создать MovieGenreRepository и добавить метод, подобный:

Stream<MovieGenre> findByGenreNameLike(String genreName);
0 голосов
/ 26 октября 2019

Прежде всего вы должны хорошо отобразить свои сущности, и если имена полей точно совпадают с вашими запросами SQL, то это будет примерно так:

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

Не забудьте поставитьаннотацию @Repository, поскольку мы всегда должны следовать стандарту гибернации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...