我目前正在嘗試 Spring boot 并使用測驗專案,我遇到了 @ManyToMany-Relationships 的問題。
應該有電影,可以保存,它們可以有多種型別、演員和類似的東西。演員可以參演很多電影。
現在我可以將電影保存到資料庫中,但由于某種原因,我只能讀出簡單的資料,比如標題或制作年份。如果我嘗試將流派列印到命令列或參與的演員,我會收到以下例外:
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.demo.Movie.actors, could not initialize proxy - no Session at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:612) at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218) at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:591) at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149) at org.hibernate.collection.internal.PersistentBag.get(PersistentBag.java:561) at com.example.demo.MoviedbApplication.main(MoviedbApplication.java:75)
這是我的代碼:
ConfigurableApplicationContext run = SpringApplication.run(MoviedbApplication.class, args);
GenreRepository genreRepository = run.getBean(GenreRepository.class);
ActorRepository actorRepository = run.getBean(ActorRepository.class);
AuthorRepository authorRepository = run.getBean(AuthorRepository.class);
DirectorRepository directorRepository = run.getBean(DirectorRepository.class);
MovieRepository movieRepository = run.getBean(MovieRepository.class);
Movie theGodfather = new Movie();
theGodfather.setTitle("Der Pate");
theGodfather.setYear(1972);
theGodfather.setOriginalTitle("The Godfather");
theGodfather.setLengthInMinutes(175);
theGodfather.setPlot("Der alternde Patriarch einer Verbrecherdynastie will die Herrschaft über sein geheimes Reich auf seinen widerwilligen Sohn übertragen.");
theGodfather.setAge(16);
List<Director> dirs = new ArrayList<>();
dirs.add(new Director("Francis Ford Coppola"));
List<Actor> acts = new ArrayList<>();
acts.add(new Actor("Marlon Brando"));
acts.add(new Actor("Al Pacino"));
acts.add(new Actor("James Caan"));
List<Genre> genres = new ArrayList<>();
genres.add(new Genre("Krimi"));
genres.add(new Genre("Drama"));
List<Author> authors = new ArrayList<>();
authors.add(new Author("Mario Puzo"));
authors.add(new Author("Francis Ford Coppola"));
theGodfather.setActors(acts);
theGodfather.setAuthors(authors);
theGodfather.setDirectors(dirs);
theGodfather.setGenres(genres);
movieRepository.save(theGodfather);
List<Movie> der_pate = movieRepository.findByTitle("Der Pate");
Movie movie = der_pate.get(0);
System.out.println("Test");
System.out.println(movie.getYear());
System.out.println(movie.getTitle());
System.out.println(movie.getId());
System.out.println(movie.getActors().get(0).getName());
System.out.println(movie.getAuthors().get(0).getName());
@Entity
@Table(name="movies")
public class Movie {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String title;
private String originalTitle;
private int year;
private int age;
private int lengthInMinutes;
private String plot;
private String linkToCover;
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinTable(
name = "movie_genres",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = @JoinColumn(name = "genre_id")
)
private List<Genre> genres = new ArrayList<>();
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinTable(
name = "movie_actors",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = @JoinColumn(name="actor_id")
)
private List<Actor> actors = new ArrayList<>();
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinTable(
name = "movie_directors",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = @JoinColumn(name = "director_id")
)
private List<Director> directors = new ArrayList<>();
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinTable(
name = "movie_authors",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = @JoinColumn(name = "author_id")
)
private List<Author> authors = new ArrayList<>();
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinTable(
name = "movie_genres",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = @JoinColumn(name = "genre_id")
)
private List<Genre> genres = new ArrayList<>();
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinTable(
name = "movie_actors",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = @JoinColumn(name="actor_id")
)
private List<Actor> actors = new ArrayList<>();
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinTable(
name = "movie_directors",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = @JoinColumn(name = "director_id")
)
private List<Director> directors = new ArrayList<>();
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinTable(
name = "movie_authors",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = @JoinColumn(name = "author_id")
)
private List<Author> authors = new ArrayList<>();
@Entity @Table(name="Actor") public class Actor {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@ManyToMany
@Cascade({CascadeType.PERSIST})
@JoinColumn(name = "movie_id")
private List<Movie> movies = new ArrayList<>();
public Actor(String name) {
this.name=name;
}`
我已經嘗試過的是將演員和流派保存到相應的存盤庫中,這會導致以下例外:
detached entity passed to persist: com.example.demo.Actor; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.demo.Actor
我還摸索著急切的獲取和東西..現在我想,我在這里錯過了一些非常重要的東西,所以我很抱歉,如果這聽起來像一個初學者的問題..
非常感謝您!
uj5u.com熱心網友回復:
它是關于獲取型別和會話管理的。如果你想訪問與你的電影相關的演員,你需要@ManyToMany(fetch = FetchType.EAGER)在這種情況下設定你的獲取型別。對于 ManyToMany 關系,默認獲取型別是 LAZY。可能,您的電影物體在從資料庫中獲取后已與會話分離。所以,即使你有movie.getActors() 行,你也會得到LazyInitializationException。有關休眠延遲加載的詳細資訊,請參閱。
https://howtodoinjava.com/hibernate/lazy-loading-in-hibernate/
uj5u.com熱心網友回復:
在您的“findByTitle”方法中,您必須加載您的 ManyToMany 關系,因為它們默認是 LAZY 獲取的。要加載集合,您可以使用 size() 方法。例如 :
List<Movie> findByTitle(String title) {
List<Movie> movies;
//fetch movies
//now load ManyToMany relationships
for(var movie : movies) {
movie.getActors().size();
movie.getAuthors().size();
}
return movies;
}
我還建議在您的多對多關系中使用 Set 而不是 List
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/451695.html
