简体   繁体   English

@ManyToMany in Spring Boot(无法延迟初始化角色集合:com.example.demo.Movie.actors,无法初始化代理 - 无会话)

[英]@ManyToMany in Spring Boot (failed to lazily initialize a collection of role: com.example.demo.Movie.actors, could not initialize proxy - no Session)

I am currently trying out Spring boot and working with a test project, I ran into a problem with @ManyToMany-Relationships.我目前正在尝试 Spring 启动并使用测试项目,我遇到了@ManyToMany-Relationships 的问题。

There should be movies, that can be saved and they can have multiple genres, actors and stuff like that.应该有可以保存的电影,它们可以有多种类型、演员等等。 The actors can take part in many movies.演员可以参加很多电影。

Now I can save the movie to the database, but for some reason I can only read out simple data, like the title or the year it was produced.现在我可以将电影保存到数据库中,但由于某种原因我只能读取简单的数据,如标题或制作年份。 If I try to print the genres to the command line, or the actors taking part, I get the following exception:如果我尝试将流派打印到命令行或参与的演员,我会得到以下异常:

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)

Here's my Code:这是我的代码:

        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;
}`

What I already tried, was saving the actors and genres to their corresponding repositories, which lead to the following exception:我已经尝试过将演员和流派保存到相应的存储库中,这会导致以下异常:

detached entity passed to persist: com.example.demo.Actor; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.demo.Actor

I also fumbled around with eager fetching and stuff..Now I think, I have missed something quite essential here, so I am sorry, if this sounds like a beginners question..我也摸索着急于获取和东西..现在我想,我在这里错过了一些非常重要的东西,所以我很抱歉,如果这听起来像一个初学者问题..

Thank you very much in advance!非常感谢您!

It is about the fetching type and session management.是关于抓取类型和session管理。 If you want to access actors associated with your movie, you need to set your fetch type as @ManyToMany(fetch = FetchType.EAGER) in this situation.如果你想访问与你的电影相关的演员,你需要在这种情况下将你的获取类型设置为@ManyToMany(fetch = FetchType.EAGER) Default fetch type is LAZY for ManyToMany relations.对于 ManyToMany 关系,默认的获取类型是 LAZY。 Probably, your movie entity was detached from session after getting it from DB.可能,您的电影实体在从 DB 获取后与 session 分离。 So, even if you have line as movie.getActors() you get LazyInitializationException.因此,即使您有作为 movie.getActors() 的行,您也会得到 LazyInitializationException。 See for detail about hibernate lazy loading.有关详细信息,请参阅 hibernate 延迟加载。 https://howtodoinjava.com/hibernate/lazy-loading-in-hibernate/ https://howtodoinjava.com/hibernate/lazy-loading-in-hibernate/

In your "findByTitle" method, you must load your ManyToMany relations as they are fetched LAZY by default.在您的“findByTitle”方法中,您必须加载 ManyToMany 关系,因为默认情况下它们是 LAZY 获取的。 To load the collections, you can use the size() method.要加载 collections,可以使用 size() 方法。 For example:例如:

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

I also suggest to use a Set instead of a List in your ManyToMany relationships我还建议在 ManyToMany 关系中使用 Set 而不是 List

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Hibernate 延迟加载不适用于 Spring 启动 =&gt; 无法延迟初始化角色集合无法初始化代理 - 没有 Session - Hibernate Lazy loading not working with Spring Boot => failed to lazily initialize a collection of role could not initialize proxy - no Session Spring Boot,无法延迟初始化角色集合,无法初始化代理 - 没有会话 - Spring Boot, Failed to lazily initialize a collection of role, could not initialize proxy - no Session 无法延迟初始化角色[]的集合,无法初始化代理-没有会话 - failed to lazily initialize a collection of role [], could not initialize proxy - no Session Hibernate 无法延迟初始化角色集合 无法初始化代理 - 没有 Session - Hibernate failed to lazily initialize a collection of role could not initialize proxy - no Session 休眠-无法延迟初始化角色集合:无法初始化代理-没有会话 - Hibernate - failed to lazily initialize a collection of role: could not initialize proxy - no Session 无法延迟初始化角色集合无法初始化代理-无会话 - Failed to lazily initialize a collection of role could not initialize proxy - no Session 无法延迟初始化角色集合:无法初始化代理-无会话 - failed to lazily initialize a collection of role : could not initialize proxy - no Session DefaultExceptionListener:未能延迟初始化角色集合无法初始化代理 - 否 Session - DefaultExceptionListener : failed to lazily initialize a collection of role could not initialize proxy - no Session Spring 数据无法延迟初始化角色集合,无法初始化代理 - 没有 Session - Spring Data failed to lazily initialize a collection of role, could not initialize proxy - no Session 未能懒惰地初始化角色集合,..无法初始化代理 - 没有会话 - JPA + SPRING - failed to lazily initialize a collection of role,..could not initialize proxy - no Session - JPA + SPRING
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM