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:
"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?
I ran into exactly the same problem. I tried the solution from the quoted paragraph, it did not work for me.
What I did is to return null for getMovie() in Clip class, then the infinite loop issue is gone. The data returned in JSON format will look like {"movieId":1 ... clips:["clipId":1, "movie":"null", ..]}.
If you also want further remove the movie property in JSON, add the class-level annotation to Clip class @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
Jackson feature: prevent serialization of nulls, default values
Update: The easier way I found is to simply remove the getter of movie in Clip class.