Comment publier entités imbriquées avec les Données du Printemps RESTE
Je suis en train de construire un Printemps de Données RESTE de l'application et je vais avoir quelques problèmes lorsque j'essaie de le POSTER. La principale entité a deux autres entités liées, imbriquées.
Il y a un "questionary" objet qui a beaucoup de réponses et chacun de ces réponses ont beaucoup de réponses.
- Je générer un JSON comme ce à partir de l'avant application pour publier le questionary:
{
"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"
}
]
}
]
}
Mais quand j'essaie de le poster, j'obtiens l'erreur de suivi de la réponse:
{
"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:
J'ai aussi ajouter mon référentiel:
@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);
}
Mon Entité Questionary classe est :
@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;
}
}
Ma Réponse Entité:
@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;
}
}
Et c'est la console d'erreur:
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*
- Pourriez-vous également afficher votre méthode de contrôleur, stacktrace et
POJO
classe? - J'ai éditer le post avec toutes les informations que vous demandez. Merci pour votre aide.
- Peut-être un problème dans les données erronées? Est-il ok:
"question": "http://localhost:8080/question/6"
. Peut-être qu'il devrait ressembler à ceci:"question": 6
. Pourquoi envoyez-vousURL
s au lieu de l'id? - Car il existe une relation entre les questions et les réponses, ces partie est ok, je l'ai essayé Individualy et fonctionne sans problème. Le problème est quand j'ai du nid et de l'objet à l'intérieur d'une autre dans une liste. Par exemple, si je fais ce post, d'abord uniquement l'inspection et un poste pour chaque réponse et une autre pour chaque réponse est de travailler mais je chose est absurde quand j'ai un questionary avec plus de 350 réponses un chacun d'entre eux ont 3 ou 4 réponses.... Il faut être un moyen de le faire dans un objet imbriqué...
- Votre définition pour les réponses prend une liste de Respuesta objets, au lieu de Répondre à des objets, est-ce une faute de frappe ou délibérée?
- C'est parce que j'ai eu l'app en espagnol et j'ai traduit tout pour le post et je ne vois pas qui. Respuesta est de même de la Réponse ;).
- Avez-vous jamais comprendre cela?
- Je crois que cette page décrit le bon moyen de faire ce travail, mais quand j'ai essayer la méthode il y a, j'obtiens le même message d'erreur que vous faites: github.com/spring-projects/spring-data-rest/wiki/...
- Même ici, avez-vous résoudre ce problème?
Vous devez vous connecter pour publier un commentaire.
Essayez d'ajouter
@RestResource(exported = false)
sur le terrainanswers
dans la classeQuestionary
.Selon moi, cette erreur se produit parce que le deserializer attend Uri pour aller chercher les réponses à partir, au lieu d'avoir les réponses imbriquées dans le JSON. L'ajout de l'annotation dit-il de regarder en JSON au lieu.
@RestResource(exported = false)
nécessaires pour être ajouté au dépôt de fichier, par exemple QuestionaryController, QuestionaryModel, QuestionaryRepo. Je ne suis pas sûr si c'est la norme au printemps ou pas, j'ai seulement travaillé avec un couple de mois pour un service principal, mais pensé qu'il pourrait aider quelqu'un dans une situation similaire.Je suis toujours de voir cette erreur avec 2.3.0.M1, mais j'ai finalement trouvé une solution de contournement.
La question fondamentale est la suivante: Si vous poster l'url de l'entité incorporé dans le JSON, il fonctionne. Si vous publiez le réel embarqué entité JSON, il ne le fait pas. Il tente de désérialiser l'entité JSON dans un URI, qui ne tient pas.
On dirait que le problème est avec les deux TypeConstrainedMappingJackson2Httpmessageconverter objets qui ressort des données de repos crée dans sa configuration (en RepositoryRestMvcConfiguration.defaultMessageConverters()).
J'ai enfin eu le problème en configurant le type de support de la messageConverters de sorte qu'il ignore ces deux et frappe la plaine MappingJackson2HttpMessageConverter, qui fonctionne très bien avec les entités imbriquées
Par exemple, si vous étendez RepositoryRestMvcConfiguration et ajouter cette méthode, puis lorsque vous envoyez une demande auprès du content-type 'application/json', il va frapper la plaine MappingJackson2HttpMessageConverter au lieu d'essayer de désérialiser en Uri:
Qui configure le message convertisseurs produit par defaultMessageConverters() dans RepositoryRestMvcConfiguration.
Gardez à l'esprit que la plaine objectMapper ne peut pas gérer les Uri dans le JSON - vous aurez toujours besoin de frapper l'un des deux préconfiguré message convertisseurs tout moment vous passez Uri de l'embedded entités.
Un problème avec votre JSON est que vous essayez de désérialiser une chaîne de caractères comme une question:
Dans votre
Answer
objet, Jackson s'attend à un objet en question. Il semble que vous utilisez des Url pour les Id, donc au lieu d'une chaîne que vous avez besoin pour passer à quelque chose comme ceci à votre question:Essayer de mettre à jour "le Printemps de Démarrage de Données RESTE Starter" de la bibliothèque. A travaillé pour moi.