编写JPQL语句不需要模型电影类型。Hibernate在执行JPQL语句时隐式地知道这一点。
SELECT m from Movie m left join m.genres g where g.name = 'Action'
双向“m.genres g”适用于所有双向JPQL语句,包括关联模型是隐式的而不是实际存在的多对多语句。
示例代码:
@Entity
@Table(name = "MOVIE")
public class Movie {
@Id
@GeneratedValue
private Long id;
@Column
private String name;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name = "movie_genre",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = {@JoinColumn(name = "genre_id")}
)
private Set<Genre> genres = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Genre> getGenres() {
return genres;
}
public void setGenres(Set<Genre> genres) {
this.genres = genres;
}
}
@Entity
@Table(name = "GENRE")
public class Genre {
@Id
@GeneratedValue
private Long id;
@Column
private String name;
@ManyToMany(mappedBy = "genres", cascade = {CascadeType.ALL})
private Set<Movie> movies = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Movie> getMovies() {
return movies;
}
public void setMovies(Set<Movie> movies) {
this.movies = movies;
}
}
@PersistenceContext
EntityManager entityManager;
@Test
@Transactional
public void test() {
Set<Movie> actionMovies = new HashSet<>();
Set<Movie> dramaMovies = new HashSet<>();
Set<Genre> dramaGenres = new HashSet<>();
Set<Genre> actionGenres = new HashSet<>();
Set<Genre> generes = new HashSet<>();
Movie actionMovie = new Movie();
actionMovie.setName("Batman");
actionMovies.add(actionMovie);
Movie dramaMovie = new Movie();
dramaMovie.setName("Forest Gump");
dramaMovies.add(dramaMovie);
Genre actionGenre = new Genre();
actionGenre.setName("Action");
generes.add(actionGenre);
actionGenres.add(actionGenre);
Genre dramaGenre = new Genre();
dramaGenre.setName("Drama");
generes.add(dramaGenre);
dramaGenres.add(dramaGenre);
//Bidirectional sets
actionGenre.setMovies(actionMovies);
dramaGenre.setMovies(dramaMovies);
actionMovie.setGenres(actionGenres);
dramaMovie.setGenres(dramaGenres);
genreRepository.saveAll(generes);
//Example JPQL join through not present association model.
Query query = entityManager.createQuery("SELECT m from Movie m left join m.genres g where g.name = 'Action'");
List<Movie> resultList = query.getResultList();
assertEquals("Batman",resultList.get(0).getName());
}