Ich entwickle Rest-Web-App mit Springframework, Hibernate und JSON. Bitte nehmen Sie an, dass ich zwei Entitäten wie unten habe:
BaseEntity.java
%Vor%Universität.java
%Vor%Student.java
%Vor%Wenn ich meine Ruhe api anrufe, um Universität zu listen, funktionieren alle Dinge gut, wie ich es erwarte, aber wenn ich meine Ruhe api nenne, um Schüler eifrig aufzulisten, ist meine JSON Antwort
%Vor%aber meine gewünschte Antwort ist:
%Vor%Update 1 : Meine Hibernate Annotation funktioniert gut Ich habe JSON Problem
Anforderungen:
Ich muss beide Seiten eifrig holen (die Uni-Seite ist Ok)
Ich brauche ein Universitätsobjekt in der Studentenseite für jeden Studenten (wenn ich Schüler eifrig abhole)
Was für eine Art von Serialisierung oder JSON-Konfiguration muss ich tun, um meine gewünschte Antwort zu finden?
Update 2:
Entfernen Sie @JsonIdentityInfo und bearbeiten Sie die Kursseite wie folgt:
%Vor%
die json Antwort immer noch gleich Ich brauche meine gewünschte Antwort, die oben erwähnt wurde.
Danke
Entferne @JsonIdentityInfo
von der Basisklasse, dies bewirkt, dass das Uni-Objekt nur die ID serialisiert.
Können Sie @JoinColumn auch zur Entität Student hinzufügen
%Vor%Überprüfen Sie auch den Fremdschlüssel Ihrer Universitätsentitätsklasse. Der Fremdschlüssel sollte von einem anderen Recht stammen? @JoinColumn (name="university_id", foreignKey = @ForeignKey (name="student_id")) ??
Alternativ können Sie auch "mappedBy" verwenden.
%Vor% Ich verstehe, dass Sie University.students
nicht in Ihren JSON aufnehmen möchten.
Entfernen Sie @JsonIdentityInfo
Fügen Sie den Schülern @JsonIgnore
hinzu, um einen Kreis zu vermeiden
Wenn Sie University.students
benötigen, um in anderen Kontexten serialisiert zu werden, geben Sie Ссылка ein lesen. Andere Möglichkeiten, mit bidirektionalen Beziehungen umzugehen, werden dort erklärt.
@jsonignore für die Getter-Methode hinzufügen
und fügen Sie @jsonProperty dem Feld hinzu
wie
Vor kurzem wurde jackson ein Feature wie Readonly und writeonly hinzugefügt
Sie können dies beziehen:
Ссылка
Sie können versuchen, @JsonRawValue
als Anmerkung für Ihre university
-Eigenschaft zu verwenden. Das Verhalten, auf das Sie stoßen, beruht auf dem Kollabieren von Referenzen. Da es sich zweimal um den gleichen University
handelt, versucht der Serializer, intelligent zu sein und gibt beim zweiten Mal eine Referenz zurück.
BEARBEITEN: Die toString()
:
Die Art, wie Sie Ihre Relationship-Map abbilden, auch wenn sie "gut funktioniert", entspricht nicht der jpa-Spezifikation für eine bidirektionale Beziehung. Siehe diese Frage und die zugehörigen Antworten.
Um zusammenzufassen, ist der Eigentümer der Beziehung normalerweise die Viele-zu-Eins-Seite und die Eins-zu-Viele-Seite ist mit mappedBy versehen. Ihre Mapping-Lösung mit der One-to-Many-Seite, die die Beziehung besitzt, ist nicht üblich / empfohlen (wie in den Antworten oben beschrieben), aber technisch möglich. (@manyToOne Seite vermisst einige Attribute wie "updatable = false" in Ihrem Beispiel)
Dann mit JPA und letzten Hibernate-Version ist die Lazy Loading-Richtlinie die folgende:
%Vor%Ich würde Ihnen daher empfehlen, diese standardmäßige Lazy-Loading-Richtlinie zu verwenden und den Besitzer Ihrer manyToOne-Beziehung zu ändern, da es keine gute Idee ist, alle Studenten über eine einzige Ressourcenanforderung der Universität zu erreichen. (Haben Sie schon von Paginierung gehört?)
Dies sollte auch der Fall sein, wenn Sie beispielsweise die Sammlung von Schülern aus dem Marshalling ausschließen, beispielsweise @JsonIgnore .
Ich hatte das gleiche Problem. Hibernate (oder Eclipselink) sind nicht das Problem. Die einzige Einschränkung in JPA ist FetchType.EAGER .
In der BaseEntity habe ich eine Standardmethode hinzugefügt
%Vor%diese Methode wäre abstrakt, aber ich hatte eine Menge Klasse und ich wollte nicht alles ändern, also habe ich einen Standardwert hinzugefügt.
Überschreiben Sie in der übergeordneten Entität, in diesem Fall der Universität, die Methode
%Vor%Verwenden Sie für jede Elternklasse ein bestimmtes Feld als Bezeichnung für Ihre Entität
Definieren Sie einen MyShandardSerializer:
%Vor%}
Fügen Sie in der Schülerklasse bei univrsity Folgendes hinzu:
%Vor%Jetzt haben Sie die Zirkularität gelöst. Wenn Sie eine Bezeichnung benötigen, überschreiben Sie die Methode in der übergeordneten Entität. Wenn Sie bestimmte Felder benötigen, erstellen Sie einen bestimmten Serializer.