2013-05-16 18 views
10

Ich habe zwei Einheiten, eine Entität "Film" und eine Entität "Clip" jeder Clip gehört zu einem Film und ein Film kann mehrere Clips haben.Hibernate @ OneToMany Beziehung verursacht unendliche Schleife oder leere Einträge in JSON Ergebnis

Mein Code sieht so aus:

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; 

Die Tabellen erzeugt werden, und jeder Clip hat eine Spalte „movie_id“, aber dies führt zu meiner Anwendung in einer Endlos-Schleife zu beenden, wenn ich Daten anfordert bin

@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... 

Es ist das gleiche Ergebnis, wenn ich einen Clip anfordere.

Wenn ich es in eine @ ManyToMany-Beziehung ändere, wird es keine Probleme geben, aber das ist nicht, was ich hier brauche. Kannst du mir helfen? Das Setzen von fetchType auf Lazy hat nicht funktioniert.

Edit: Ich bin mit dem aktuellen Entwicklung Studio JBoss

Edit:

I "gelöst" dies durch diesen Artikel lesen:

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

„eine bidirektionale Zur Karte Eins zu viele, mit der Eins-zu-Vielen-Seite als Eigentümerseite müssen Sie das mappedBy-Element entfernen und die Viele-zu-Eins @JoinColumn als einfügbar und aktualisierbar auf false setzen Diese Lösung ist offensichtlich nicht optimiert und erzeugt etwas hinzufügen itionale UPDATE-Anweisungen. "

, wenn ich bitte einen Film, den ich die folgende Antwort erhalten:

{ "id": 1 "Version": 1, "name": "MGS Lösungsweg", "Dateiname": "video.mp4" , "movieCategories": [{"id": 1, "version": 1, "name": "Walkthrough"}], "clips": [], "description": "Trailer zu mgs4"}

Der Eintrag "Clips" erscheint weiterhin. Ist das immer noch die falsche Lösung oder muss ich damit leben?

Antwort

10

Ich stieß genau auf das gleiche Problem. Ich habe versucht, die Lösung aus dem zitierten Absatz, es hat nicht funktioniert für mich.

Was ich getan habe, ist, null für getMovie() in Clip-Klasse zurückzugeben, dann ist das Endlosschleife Problem verschwunden. Die im JSON-Format zurückgegebenen Daten sehen wie {"movieId": 1 ... clips aus: ["clipId": 1, "movie": "null", ..]}.

Wenn Sie den Film auch Immobilien in JSON entfernen möchten weiter, fügen Sie die Klasse-Level-Annotation-Klasse @JsonSerialize (include = JsonSerialize.Inclusion.NON_NULL)

Jackson feature: prevent serialization of nulls, default values

Update Clip: Die einfacherer Weg, den ich gefunden habe, ist, den Getter des Filmes in der Klippklasse einfach zu entfernen.

+0

Ihr Update hat mir wirklich geholfen – elysch

+0

Das Entfernen der Getter löste mein Problem. Vielen Dank! –

+0

Ihr Update hat meinen Tag gerettet! – SuperGirl

1

Anstatt ein Entity-Objekt zurückzugeben, empfehle ich, ein DTO-Objekt nur mit den benötigten Daten zurückzugeben. Sie können einen direkt aus einem Hibernate-Abfrage-/Kriterienergebnis mithilfe von Ergebnistransformatoren abrufen.

1

Wie Sie sagen "die Eintragsclips erscheinen immer noch".

Um die Beziehungsdaten in der db-Antwort zu vermeiden, ändern Sie fetch = FetchType.EAGER in fetch = FetchType.Lazy.

0

Lösung:

Verwenden

@JsonManagedReference Annotation für die ersten Objekte instanziiert

@JsonBackReference Annotation für die zweiten Objekte instanziiert

Movie.java

Cl ip.java

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