Konnte nicht schreiben, JSON: fehlgeschlagen zu faul initialisieren eine Sammlung von Rolle
Ich bin die Realisierung eines server-REST mit dem java - hibernate - spring, das gibt einen json -
Ich habe die Karte eine viele zu viele Beziehung.
Ich besser erklären, ich habe ein Lieferant, dass eine Liste der Zutaten und jede Zutat hat eine Liste von Lieferanten.
Ich die Tabelle erstellt:
CREATE TABLE supplier_ingredient (
supplier_id BIGINT,
ingredient_id BIGINT
)
ALTER TABLE supplier_ingredient ADD CONSTRAINT supplier_ingredient_pkey
PRIMARY KEY(supplier_id, ingredient_id);
ALTER TABLE supplier_ingredient ADD CONSTRAINT
fk_supplier_ingredient_ingredient_id FOREIGN KEY (ingredient_id)
REFERENCES ingredient(id);
ALTER TABLE supplier_ingredient ADD CONSTRAINT
fk_supplier_ingredient_supplier_id FOREIGN KEY (supplier_id) REFERENCES
supplier(id);
Dann habe ich Zutat Modell:
.....
.....
@ManyToMany(mappedBy = "ingredients")
@OrderBy("created DESC")
@BatchSize(size = 1000)
private List<Supplier> suppliers = new ArrayList<>();
....
....
Dann habe ich Lieferanten Modell:
....
@ManyToMany
@JoinTable( name = "supplier_ingredient ",
joinColumns = @JoinColumn(name = "supplier_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "ingredient_id", referencedColumnName = "id"),
foreignKey = @ForeignKey(name = "fk_supplier_ingredient_supplier_id"))
@OrderBy("created DESC")
@Cascade(CascadeType.SAVE_UPDATE)
@BatchSize(size = 1000)
private List<Ingredient> ingredients = new ArrayList<>();
....
Endpunkt:
@RequestMapping(value = "/{supplierId:[0-9]+}", method = RequestMethod.GET)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
public SupplierObject get(@PathVariable Long supplierId) {
Supplier supplier = supplierService.get(supplierId);
SupplierObject supplierObject = new SupplierObject (supplier);
return SupplierObject;
}
Service
....
public Supplier get(Long supplierId) {
Supplier supplier = supplierDao.getById(supplierId); (it does entityManager.find(entityClass, id))
if (supplier == null) throw new ResourceNotFound("supplier", supplierId);
return supplier;
}
....
SupplierObject
@JsonIgnoreProperties(ignoreUnknown = true)
public class SupplierObject extends IdAbstractObject {
public String email;
public String phoneNumber;
public String address;
public String responsible;
public String companyName;
public String vat;
public List<Ingredient> ingredients = new ArrayList<>();
public SupplierObject () {
}
public SupplierObject (Supplier supplier) {
id = supplier.getId();
email = supplier.getEmail();
responsible = supplier.getResponsible();
companyName = supplier.getCompanyName();
phoneNumber = supplier.getPhone_number();
ingredients = supplier.getIngredients();
vat = supplier.getVat();
address = supplier.getAddress();
}
}
Und IdAbstractObject
public abstract class IdAbstractObject{
public Long id;
}
Mein problem ist, wenn ich Anrufe, die Endpunkt:
http://localhost:8080/supplier/1
Ich bekam eine Fehlermeldung:
"Could not write JSON: fehlgeschlagen zu faul initialisieren einer Sammlung von
Rolle: MeinPaket.Inhaltsstoff.Inhaltsstoff.Lieferanten, die nicht initialisiert werden konnte
proxy - keine Sitzung; verschachtelte Ausnahme ist
com.fasterxml.jackson.databind-Methode.JsonMappingException: fehlgeschlagen zu faul
initialize a collection of role:
MeinPaket.Inhaltsstoff.Inhaltsstoff.Lieferanten, die nicht initialisiert werden konnte-proxy
- keine Sitzung (durch Verweis Kette: myPackage.supplier.SupplierObject[\"ingredients\"]->org.hibernate.collection.internal.PersistentBag[0]->myPackage.ingredient.Ingredient[\"suppliers\"])"
Was habe ich falsch gemacht?
@Nikhil Yekhe
Ich folgte dies:
Vermeiden Jackson Serialisierung auf nicht geholt faul Objekte
Jetzt habe ich nicht die Fehler, sondern in json zurückgegeben, die Zutaten, die Feld null ist:
{
"id": 1,
"email": "[email protected]",
"phoneNumber": null,
"address": null,
"responsible": null,
"companyName": "Company name",
"vat": "vat number",
"ingredients": null
}
aber Debuggen kann ich sehen, Zutaten....
InformationsquelleAutor Gjord83 | 2018-01-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist das normale Verhalten von Hibernate und Jackson Marshaller
Im Grunde möchten Sie, dass die folgenden: ein JSON mit allen Anbieter-Objekt-details... enthalten die Zutaten.
Bitte beachten Sie, dass in diesem Fall müssen Sie sehr vorsichtig, denn Sie können eine zyklische Referenz wenn Sie versuchen, erstellen der JSON selbst, so dass Sie verwenden sollten, auch
JsonIgnore
annotationDas erste, was Sie tun müssen, ist laden Sie die Lieferanten und alle seine details (Zutaten enthalten).
Wie können Sie es tun? Durch die Verwendung mehrerer Strategien... benutze mal die
Hibernate.initialisieren
. Diese muss verwendet werden, vor dem schließen der hibernate-session, in der das DAO (oder repository) Umsetzung (im Grunde, wo Sie mit der hibernate-session).So, in diesem Fall (ich nehme an, zu verwenden, Hibernate) in meiner repository-Klasse sollte ich etwas schreiben wie:
Nun haben Sie die
Supplier
Objekt mit all seinen eigenen Angaben (Ingredients
auch)Jetzt in Ihrem Dienst, den Sie tun können, was Sie getan haben, ist:
In dieser Art und Weise Jackson in der Lage ist, in das schreiben der JSON -
but
lassen Sie uns einen Blick auf dieIngredient
Objekt.. es hat die folgende Eigenschaft:Was passiert, wenn Jackson versucht, den JSON? Es wird der Zugriff auf die einzelnen element innerhalb der
List<Ingredient>
und es wird versuchen, erstellen Sie eine JSON-für diese ein.... auch für die Lieferanten-Liste und dies ist eine zyklische Referenz... so müssen Sie es vermeiden, und Sie können dies vermeiden, indem mithilfe der JsonIgnore annotation. Zum Beispiel können Sie schreiben Sie IhreIngredient
entity-Klasse, die in dieser Weise:In dieser Art und Weise Sie:
In jedem Fall würde ich vorschlagen, Sie erstellen spezifische DTO (oder VO) - Objekt für marshalling und unmarshalling JSONs
Ich hoffe, dies ist nützlich
Angelo
InformationsquelleAutor Angelo Immediata
In mein Projekt kam ich auf das gleiche problem wie Ihr. Das problem ist, dass durch die Zeit, die zum Lesen der Daten "one to many" ist die session bereits geschlossen wurde. Um all die Daten, die Sie benötigen, um explizit zu initialisieren, oder verwenden Sie die Transaktion. Ich habe eine explizite Initialisierung.
Sie müssen fügen Sie eine Zeile in der DAO:
Danach, Hibernate lädt alle Daten aus der Datenbank. Um zu vermeiden Erzeugung eine Ausnahme, wenn JSON serialisiert wird, füge ich die
@JsonIgnore
Anmerkung in der eins-zu-viele-Modell Bereich.Hier ein Beispiel von meinem code:
1.Modell
2. DAO
InformationsquelleAutor conacry
Dies ist aufgrund der hibernate-session geschlossen wird, bevor die verzögerte Initialisierung getreten.
Die Lösung ist gut erklärt bei dieser Antwort unten.
Vermeiden Jackson Serialisierung auf nicht geholt faul Objekte
hi @Nikhil, ich aktualisierte meine Frage mit deinem Vorschlag....
InformationsquelleAutor Nikhil Yekhe
Fügen Sie einfach
@JsonIgnore
nach@oneToMany
in Ihrer model-Klasse.InformationsquelleAutor Majid