Как правильно POST к двунаправленным отношениям - PullRequest
1 голос
/ 28 марта 2019

Итак, я реализую API, используя springboot, spring-data и Jackson, но у меня возникают некоторые проблемы, когда я пытаюсь отправить запрос к конечной точке, у которой есть отношение двунаправленности @ OneToMany.

У меня неттак много предыстории, поэтому мне действительно нужна помощь.

У меня есть две сущности:

Партида

package lucas.duarte.jazz.model.bean;

import java.io.Serializable;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonProperty;

@Entity
public class Partida implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String timeA;
    private String timeB;
    private boolean visitante;
    @OneToMany(mappedBy = "partida", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Set> sets;


    public List<Set> getSets() {
        return sets;
    }

    public void setSets(List<Set> sets) {
        this.sets = sets;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTimeA() {
        return timeA;
    }

    // Mocado o valor pois o Time A sempre e a Sao Judas
    public void setTimeA(String timeA) {
        this.timeA = timeA;
    }

    public String getTimeB() {
        return timeB;
    }

    public void setTimeB(String timeB) {
        this.timeB = timeB;
    }

    public boolean isVisitante() {
        return visitante;
    }

    public void setVisitante(boolean visitante) {
        this.visitante = visitante;
    }

}

и SET

package lucas.duarte.jazz.model.bean;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@Entity
@Table(name = "meu_set")
public class Set implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "ponto_a")
    private long pontoA;
    @Column(name = "ponto_b")
    private long pontoB;
    @Column(name = "set_finalizado")
    private boolean setFinalizado;
    @ManyToOne
    @JoinColumn(name = "partida_id")
    private Partida partida;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public long getPontoA() {
        return pontoA;
    }

    public void setPontoA(long pontoA) {
        this.pontoA = pontoA;
    }

    public long getPontoB() {
        return pontoB;
    }

    public void setPontoB(long pontoB) {
        this.pontoB = pontoB;
    }

    public boolean isSetFinalizado() {
        return setFinalizado;
    }

    public void setSetFinalizado(boolean setFinalizado) {
        this.setFinalizado = setFinalizado;
    }

    public Partida getPartida() {
        return partida;
    }

    public void setPartida(Partida partida) {
        this.partida = partida;
    }

}

Это мойSetControler

package lucas.duarte.jazz.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.util.UriComponentsBuilder;

import lucas.duarte.jazz.model.bean.Set;
import lucas.duarte.jazz.model.service.SetService;

@Controller
@RequestMapping("/api")
public class SetController {

    private SetService setServ;

    @RequestMapping(value = "/set/", method = RequestMethod.POST)
    public ResponseEntity<?> salvarSet(@RequestBody Set set, UriComponentsBuilder ucBuilder) {
        System.out.println("Vou cadastrar um set vinculado a uma partida");
        System.out.println(set.getPartida().getId());
        setServ.salvarSet(set);
        return new ResponseEntity(HttpStatus.CREATED);
    }

}

Когда я POST к URL, я получаю следующее возвращение

{
    "timestamp": "2019-03-28T04:17:46.857+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "JSON parse error: Cannot construct instance of `lucas.duarte.jazz.model.bean.Partida` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `lucas.duarte.jazz.model.bean.Partida` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)\n at [Source: (PushbackInputStream); line: 5, column: 14] (through reference chain: lucas.duarte.jazz.model.bean.Set[\"partida\"])",
    "path": "/api/set/"
}

У меня уже есть Partida в моей базе данных, ноЯ не могу отправить этот метод, нужна действительно помощь.

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Эта проблема не имеет ничего общего с двунаправленным отображением JPA. Его ошибка поднятия во время десериализации.
Partida -> должен иметь конструктор с нулевым аргументом

Запрос полезной нагрузки должен иметь {"partida": {"id": 123}} для заполнения свойства объекта partida.

0 голосов
/ 28 марта 2019

для получения подробной информации проверьте эту ссылку Библиотека Джексона .

@Entity
public class Partida implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String timeA;
    private String timeB;
    private boolean visitante;
    public  Partida(){
    //Default constructor required here 
    }
    @OneToMany(mappedBy = "partida", fetch = FetchType.LAZY, cascade = 
    CascadeType.ALL)
    private List<Set> sets;


    public List<Set> getSets() {
        return sets;
    }

    public void setSets(List<Set> sets) {
        this.sets = sets;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTimeA() {
        return timeA;
    }

    // Mocado o valor pois o Time A sempre e a Sao Judas
    public void setTimeA(String timeA) {
        this.timeA = timeA;
    }

    public String getTimeB() {
        return timeB;
    }

    public void setTimeB(String timeB) {
        this.timeB = timeB;
    }

    public boolean isVisitante() {
        return visitante;
    }

    public void setVisitante(boolean visitante) {
        this.visitante = visitante;
    }

}

, если проблема не решена, попробуйте JSON creator

@JsonCreator
    public Partida(@JsonProperty("id") Long id, @JsonProperty("timeA") String 
    timeA, @JsonProperty("timeB") String timeB, @JsonProperty("desc") boolean
    visitante) {
    this.id = id;
    this.timeA = timeA;
    this.timeB= timeB;
    this.visitante= visitante;
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...