JPA crud存储库查询



我试图学习Spring,但遇到了JPA存储库查询的问题我有两个相互之间双向关系的类:

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_idn" +
"INNER JOIN movie_genre mg ON mmg.movie_genre_id = mg.genre_idn" +
"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查询不可能,如何编写正确的自定义查询?

  • 编辑:--我将查询更改为"SELECT m FROM Movie m INNER JOIN m.types g WHERE g.genreName=?1"(如以下答案所示(--另一个问题是控制器中缺少@Transactional注释。

尝试从使用本机查询切换到jpql概念:

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

或者,您可以创建一个MovieGenreRepository,并使用以下方法:

Stream<MovieGenre> findByGenreNameLike(String genreName);

首先,您必须很好地映射实体,如果字段的名称与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注释,因为我们必须始终遵循hibernate标准。

相关内容

最新更新