So verschachteln Sie Entitäten mit Spring Data REST
Baue ich eine Spring Data REST-Anwendung und ich habe einige Probleme wenn ich versuche zu POSTEN. Die Hauptorganisation hat die anderen zwei verbundene Einheiten geschachtelt sind.
Gibt es eine "Abfrage" Objekt, das die vielen Antworten und jede dieser Antworten haben viele Antworten.
Generiere ich eine JSON-wie dies von der Vorderseite Anwendung für die POST Abfrage:
{
"user": "http://localhost:8080/users/1",
"status": 1,
"answers": [
{
"img": "urlOfImg",
"question": "http://localhost:8080/question/6",
"replies": [
{
"literal": "http://localhost:8080/literal/1",
"result": "6"
},
{
"literal": "http://localhost:8080/literal/1",
"result": "6"
}
]
},
{
"img": "urlOfImg",
"question": "http://localhost:8080/question/6",
"replies": [
{
"literal": "http://localhost:8080/literal/3",
"result": "10"
}
]
}
]
}
Aber wenn ich versuche, es zu senden, bekomme ich folgende Fehler-Antwort:
{
"cause" : {
"cause" : {
"cause" : null,
"message" : "Template must not be null or empty!"
},
"message" : "Template must not be null or empty! (through reference chain: project.models.Questionary[\"answers\"])"
},
"message" : "Could not read JSON: Template must not be null or empty! (through reference chain: project.models.Questionary[\"answers\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Template must not be null or empty! (through reference chain: project.models.Questionary[\"answers\"])"
}
Edit:
Stell ich auch mein repository:
@RepositoryRestResource(collectionResourceRel = "questionaries", path = "questionaries")
public interface InspeccionRepository extends JpaRepository<Inspeccion, Integer> {
@RestResource(rel="byUser", path="byUser")
public List<Questionary> findByUser (@Param("user") User user);
}
Meiner Entität Fragebogen Klasse ist :
@Entity @Table(name="QUESTIONARY", schema="enco" )
public class Questionary implements Serializable {
private static final long serialVersionUID = 1L;
//----------------------------------------------------------------------
//ENTITY PRIMARY KEY ( BASED ON A SINGLE FIELD )
//----------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEC_QUESTIONARY")
@SequenceGenerator(name = "SEC_QUESTIONARY", sequenceName = "ENCO.SEC_QUESTIONARY", allocationSize = 1)
@Column(name="IDQUES", nullable=false)
private Integer idques ;
//----------------------------------------------------------------------
//ENTITY DATA FIELDS
//----------------------------------------------------------------------
@Column(name="ESTATUS")
private Integer estatus ;
//----------------------------------------------------------------------
//ENTITY LINKS ( RELATIONSHIP )
//----------------------------------------------------------------------
@ManyToOne
@JoinColumn(name="IDUSER", referencedColumnName="IDUSER")
private User user;
@OneToMany(mappedBy="questionary", targetEntity=Answer.class)
private List<Answer> answers;
//----------------------------------------------------------------------
//CONSTRUCTOR(S)
//----------------------------------------------------------------------
public Questionary()
{
super();
}
//----------------------------------------------------------------------
//GETTERS & SETTERS FOR FIELDS
//----------------------------------------------------------------------
//--- DATABASE MAPPING : IDNSE ( NUMBER )
public void setIdnse( Integer idnse )
{
this.idnse = idnse;
}
public Integer getIdnse()
{
return this.idnse;
}
//--- DATABASE MAPPING : ESTADO ( NUMBER )
public void setEstatus Integer estatus )
{
this.estatus = estatus;
}
public Integer getEstatus()
{
return this.estatus;
}
//----------------------------------------------------------------------
//GETTERS & SETTERS FOR LINKS
//----------------------------------------------------------------------
public void setUser( Usuario user )
{
this.user = user;
}
public User getUser()
{
return this.user;
}
public void setAnswers( List<Respuesta> answers )
{
this.answers = answer;
}
public List<Answer> getAnswers()
{
return this.answers;
}
//Get Complete Object method public List<Answer>
getAnswerComplete() {
List<Answer> answers = this.answers;
return answers;
}
}
Meine Antwort Einheit:
@Entity @Table(name="ANSWER", schema="enco" ) public class Answer
implements Serializable {
private static final long serialVersionUID = 1L;
//----------------------------------------------------------------------
//ENTITY PRIMARY KEY ( BASED ON A SINGLE FIELD )
//----------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEC_ANSWER")
@SequenceGenerator(name = "SEC_ANSWER", sequenceName = "ENCOADMIN.SEC_ANSWER", allocationSize = 1)
@Column(name="IDANS", nullable=false)
private Integer idans ;
//----------------------------------------------------------------------
//ENTITY DATA FIELDS
//----------------------------------------------------------------------
@Column(name="IMG", length=100)
private String img ;
//----------------------------------------------------------------------
//ENTITY LINKS ( RELATIONSHIP )
//----------------------------------------------------------------------
@ManyToOne
@JoinColumn(name="IDQUES", referencedColumnName="IDQUES")
private Questionary questionary ;
@OneToMany(mappedBy="answer", targetEntity=Reply.class)
private List<Reply> replies;
@ManyToOne
@JoinColumn(name="IDQUE", referencedColumnName="IDQUE")
private Question Question ;
//----------------------------------------------------------------------
//CONSTRUCTOR(S)
//----------------------------------------------------------------------
public Answer()
{
super();
}
//----------------------------------------------------------------------
//GETTER & SETTER FOR THE KEY FIELD
//----------------------------------------------------------------------
public void setIdans( Integer idans )
{
this.idans = idans ;
}
public Integer getIdans()
{
return this.idans;
}
//----------------------------------------------------------------------
//GETTERS & SETTERS FOR FIELDS
//----------------------------------------------------------------------
//--- DATABASE MAPPING : IMAGEN ( VARCHAR2 )
public void setImg( String img )
{
this.img = img;
}
public String getImg()
{
return this.img;
}
//----------------------------------------------------------------------
//GETTERS & SETTERS FOR LINKS
//----------------------------------------------------------------------
public void setQuestionary( Questionary questionary )
{
this.questionary = questionary;
}
public Questionary getQuestionary()
{
return this.questionary;
}
public void setReplies( List<Reply> contestaciones )
{
this.replies = replies;
}
public List<Reply> getReplies()
{
return this.replies;
}
public void setQuestion( Question question )
{
this.question = question;
}
public Question getQuestion()
{
return this.question;
}
}
- Und dies ist der Fehler-Konsole:
Caused by: com.fasterxml.jackson.databind.JsonMappingException:
Template must not be null or empty! (through reference chain:
project.models.Questionary["answers"]) at
com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
~[jackson-databind-2.3.3.jar:2.3.3] at *snip*
InformationsquelleAutor der Frage 73nko | 2014-07-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Versuchen Sie
@RestResource(exported = false)
auf Feldanswers
in der KlasseQuestionary
.Nach mir, dieser Fehler tritt auf, weil der deserializer erwartet URIs zum abrufen der Antworten aus, anstatt die Antworten in der verschachtelten JSON. Hinzufügen der Anmerkung sagt er zu Blick in JSON statt.
InformationsquelleAutor der Antwort Gauthier JACQUES
Ich bin immer noch zu sehen, dieser Fehler mit 2.3.0.M1, aber schließlich fand ich einen workaround.
Die grundlegende Frage ist diese: Wenn Sie nach der url des eingebetteten Entität in der JSON -, es funktioniert. Wenn Sie nach der tatsächlichen eingebettete Entität JSON, gibt es nicht. Es versucht zu Deserialisieren der Person JSON in eine URI, die natürlich auch nicht.
Wie es aussieht ist das Problem mit den zwei TypeConstrainedMappingJackson2Httpmessageconverter Objekte, spring data rest schafft in seiner Konfiguration (in RepositoryRestMvcConfiguration.defaultMessageConverters()).
Schließlich bekam ich rund um die Problem durch konfigurieren der unterstützten media-Typen der messageConverters, so dass es überspringt die beiden und trifft die Ebene MappingJackson2HttpMessageConverter, die gut funktioniert mit verschachtelten Entitäten.
Zum Beispiel, wenn Sie erweitern RepositoryRestMvcConfiguration und fügen Sie diese Methode, dann, wenn Sie senden Sie eine Anfrage mit dem content-type 'application/json', auf der Ebene MappingJackson2HttpMessageConverter anstatt zu versuchen, zu Deserialisieren in URIs:
Konfiguration der message-Wandler produziert von defaultMessageConverters() in RepositoryRestMvcConfiguration.
Beachten Sie, dass die Ebene objectMapper nicht verarbeiten können URIs in den JSON - du musst noch drücken Sie eine der zwei vorkonfigurierte Nachricht-Wandler jedes mal passieren Sie-URIs eingebettet Entitäten.
InformationsquelleAutor der Antwort TLA
Ein Problem mit dem JSON ist, dass Sie versuchen, zu deserialisiert einen string als Frage:
In Ihrem
Answer
Objekt, Jackson erwartet Sie ein Objekt für die Frage. Es scheint, dass Sie mithilfe von URLs für die IDs, so dass anstelle einer Zeichenfolge übergeben zu müssen, so etwas wie dies für Ihre Frage:InformationsquelleAutor der Antwort Sam Berry
Versuchen Sie zu aktualisieren "Spring Boot-Daten REST Starter" - Bibliothek. Arbeitete für mich.
InformationsquelleAutor der Antwort christinasantz