Hibernate @OneToMany Relationship Causes Infinite

2020-03-10 02:50发布

I have two entities, an entity "movie" and an entity "Clip" each clip belongs to one movie and a movie can have multiple clips.

My code looks like:

Movie.java
    @OneToMany(mappedBy = "movie", targetEntity = Clip.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<Clip> clips = new HashSet<Clip>();



 Clip.java

    @ManyToOne
        @JoinColumn(name="movie_id")
        private Movie movie;

The tables are being generated and each Clip has a column "movie_id" but this causes my application to end up in an infinite loop when I'm requesting Data

    @Path("/{id:[0-9][0-9]*}")
        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public Movie lookupMovieById(@PathParam("id") long id) {
            return em.find(Movie.class, id);
        }


result:
{"id":1,"version":1,"name":"MGS Walkthrough","filename":"video.mp4","movieCategories":[{"id":1,"version":1,"name":"Walkthrough"}],"clips":[{"id":1,"version":1,"name":"MGS Walkthrough P1","keywords":null,"movie":{"id":1,"version":1,"name":"MGS Walkthrough","filename":"video.mp4","movieCategories":[{"id":1,"version":1,"name":"Walkthrough"}],"clips":[{"id":1,"version":1,"name":"MGS Walkthrough P1","keywords":null,"movie":{"id":1,"version":1,"name":"MGS Walkthrough","filename":"video.mp4","movieCategories":[{"id":1,"version":1,"name":"Walkthrough"}],"clips":[{"id":1,"version":1,"name":"M...

It's the same result when I'm requesting a clip.

When I change it to a @ManyToMany relationship there won't be any problems like that, but that's not what I need here. Can you help me? Setting fetchType to Lazy didn't work.

Edit: I'm using the current JBoss development studio

Edit:

I "solved" this, by reading this article:

http://blog.jonasbandi.net/2009/02/help-needed-mapping-bidirectional-list.html

"To map a bidirectional one to many, with the one-to-many side as the owning side, you have to remove the mappedBy element and set the many to one @JoinColumn as insertable and updatable to false. This solution is obviously not optimized and will produce some additional UPDATE statements."

when I request a movie I get the following answer:

{"id":1,"version":1,"name":"MGS Walkthrough","filename":"video.mp4","movieCategories":[{"id":1,"version":1,"name":"Walkthrough"}],"clips":[],"description":"Trailer zu mgs4"}

the entry "clips" still appears. Is this still the wrong solution or do I just have to live with this?

9条回答
啃猪蹄的小仙女
2楼-- · 2020-03-10 03:25

Easy way as Dino Tw said:

Remove the getMovie() function from the Clip class.

That will help you to retrieve the Clip list for each Movie which is associated by movie_id in the Clip entity/table.

查看更多
家丑人穷心不美
3楼-- · 2020-03-10 03:26

Need to add @JsonIgnore in child class to avoid such exception. Be careful not to add this annotation in Parent class

@Entity  
@Table(name="Movie")
public class Movie implements Serializable{

@OneToMany(mappedBy="movie",targetEntity=Clip.class,cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
private Set<Clip> clips = new HashSet<Clip>();

}

@Entity  
@Table(name="Clip")
public class Clip implements Serializable{   
    @ManyToOne
    @JoinColumn(name="movie_id")
    @JsonIgnore
    private Movie movie;
}
查看更多
仙女界的扛把子
4楼-- · 2020-03-10 03:27

Solution:

Use

@JsonManagedReference annotation for the first objects instantiated

@JsonBackReference annotation for the second objects instantiated

Movie.java

@JsonManagedReference
@OneToMany(mappedBy = "movie", targetEntity = Clip.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<Clip> clips = new HashSet<Clip>();

Clip.java

@JsonBackReference
@ManyToOne
    @JoinColumn(name="movie_id")
    private Movie movie;
查看更多
登录 后发表回答