Ich arbeite an API Rest Projekt mit Spring. Ich habe einen Dienst "CreateMateriel", die als Parameterdaten JSON nimmt:Deserialize JSON mit Frühling: Ungelöste Vorwärtsreferenzen Jackson Exception
JSON von Materiel Objekt
{
"agence": 1,
"code": "001",
"type": "MyType"
}
"Materiel" hat eine Beziehung Viele zu Eins mit "Agence". Ich habe einen @JsonIdentityInfo Tag Agence des Id zu verwenden und nicht Agence Object (Nach der Besichtigung this topic)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "idAgence")
@JsonIdentityReference(alwaysAsId = true)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "agence")
private Agence agence;
Aber wenn ich JSON auf POST/materiels senden habe ich diese Ausnahme:
2017-05-16 18:00:53.021 WARN 8080 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Unresolved forward references for:
at [Source: [email protected]; line: 5, column: 1]Object id [1] (for fr.app.domain.Agence) at [Source: [email protected]; line: 2, column: 14].; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for:
at [Source: [email protected]; line: 5, column: 1]Object id [1] (for fr.app.domain.Agence) at [Source: [email protected]; line: 2, column: 14].
Nach vielen Forschungs Ich habe die Verwendung von ObjectIdResolver in JsonIdentityInfo gesehen ... Aber ich denke, das ist nicht die beste Lösung. Deshalb bitte ich um Ihre Hilfe bei der Erkennung der Ursache des Problems. des Thank
MaterielController.java
package fr.app.controllers;
import fr.app.domain.Materiel;
import fr.app.services.MaterielService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Collection;
@RestController @RequestMapping(value = "/materiels")
public class MaterielController {
@Resource
private MaterielService materielService;
@RequestMapping(method = RequestMethod.POST)
public Materiel createMateriel(@RequestBody Materiel materiel) {
return this.materielService.createMateriel(materiel);
}
@RequestMapping(method = RequestMethod.GET)
public Collection<Materiel> getAllMateriels() {
return this.materielService.getAllMateriels();
}
@RequestMapping(value = "/{code}", method = RequestMethod.GET)
public Materiel getMaterielByCode(@PathVariable(value = "code") String code) {
//find materiel by code
return this.materielService.getMaterielByCode(code);
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public void deleteMateriel(@PathVariable(value = "id") Long id) {
this.materielService.deleteMateriel(id);
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public Materiel updateMateriel(@PathVariable(value = "id") Long id, @RequestBody
Materiel materiel) {
materiel.setIdMateriel(id);
return this.materielService.updateMateriel(materiel);
}
}
Materiel.java
package fr.app.domain;
import com.fasterxml.jackson.annotation.*;
import javax.persistence.*;
@Entity
public class Materiel {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long idMateriel;
@Column(name = "type_materiel", nullable = false)
private String type;
@Column(name = "code_materiel", unique = true, nullable = false)
private String code;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "idAgence")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "agence")
private Agence agence;
public Materiel() { }
public Materiel(String type, String code, String dateScan) {
this.type = type;
this.code = code;
this.dateScan = dateScan;
}
public Long getIdMateriel() {
return idMateriel;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Agence getAgence() {
return agence;
}
public void setAgence(Agence agence) {
if(this.agence != null)
this.agence.deleteMateriel(this);
this.agence = agence;
this.agence.addMateriel(this);
}
}
MaterielService.java
package fr.app.services;
import fr.app.domain.Materiel;
import fr.app.repositories.MaterielRepository;
import org.apache.commons.collections.IteratorUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collection;
@Service(value = "materielService")
public class MaterielServiceImpl implements MaterielService {
@Resource
private MaterielRepository materielRepository;
...
@Override
public Materiel createMateriel(Materiel materiel) {
return this.materielRepository.save(materiel);
}
...
}
Agence.java
package fr.app.domain;
import com.fasterxml.jackson.annotation.*;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Entity
public class Agence {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long idAgence;
@Column(name = "nom",unique = true, nullable = false)
private String nom;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "agence")
private Set<Materiel> materiels = new HashSet<Materiel>();
public Agence() { }
public Agence(String nom) {
this.nom = nom;
}
public Long getIdAgence() {
return idAgence;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public Set<Materiel> getMateriels() {
return materiels;
}
public void setMateriels(Set<Materiel> materiels) {
this.materiels = materiels;
}
public void addMateriel(Materiel materiel) {
this.materiels.add(materiel);
}
public void deleteMateriel(Materiel materiel) {
this.materiels.remove(materiel);
}
}
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.9.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.9.Final</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>
<!-- Needed for JSON View -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
'Matiriel' hat Verweise auf' Agency' und 'Agency' hat Verweise auf' Matiriel' die führen zu zirkulären Referenzen. Sie müssen '@ JsonIgnore' zu einem von ihnen hinzufügen. – jny