How to deal with @OneToMany relation in REST

天大地大妈咪最大 提交于 2019-12-08 05:45:48

问题


I'm designing a small REST application that allows to perform some basic operations. So far so good, i have following @Entity called Client that needs to be persisted along side with @Entity called Loan:

Client:

@Entity
@Table(name = "clients")
public class Client{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "CLIENT_ID")
    private Long id;

    private String name;
    private String surname;
    private String email;
    private String phone;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "client")
    private Set<Loan> loans;

    public Client() {}

    public Client(Long id, String name, String surname, String email, String phone) {
        this.id = id;
        this.name = name;
        this.surname = surname;
        this.email = email;
        this.phone = phone;
    }

   // getters/setters

}

Loan:

@Entity
@Table(name = "loans")
public class Loan{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CLIENT_ID")
    private Client client;

    @Temporal(TemporalType.DATE)
    private Date startDate = new Date();

    @Temporal(TemporalType.DATE)
    private Date originTerm;

    private Float maxPossibleAmount;

    private String notes;

    public Loan() {}

    public Loan(Long id, Client client, Date startDate, Date originTerm, Float maxPossibleAmount, String notes) {
        this.id = id;
        this.client = client;
        this.startDate = startDate;
        this.originTerm = originTerm;
        this.maxPossibleAmount = maxPossibleAmount;
        this.notes = notes;
    }

 // getters/setters
}

Registering Client works flawlessly, via postman, however i can't to understand how to register loan for a specific client. On attempt to do so, PostMan refuses to register new loan with the following message:

{ "timestamp": 1504429329213, "status": 400, "error": "Bad Request", "exception": "org.springframework.http.converter.HttpMessageNotReadableException", "message": "JSON parse error: Can not construct instance of com.reborn.xxx.backend.models.Client: no int/Int-argument constructor/factory method to deserialize from Number value (1); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.reborn.xxx.backend.models.Client: no int/Int-argument constructor/factory method to deserialize from Number value (1)\n at [Source: java.io.PushbackInputStream@121b34b; line: 3, column: 12] (through reference chain: com.reborn.xxx.backend.models.Loan[\"client\"])", "path": "/api/loans/add" }

LoanController:

@RestController
@RequestMapping(value = "/api/loans")
public class LoanController extends BaseController {

    @Autowired
    private LoanService loanService;

    @RequestMapping(value = "/add", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity registerLoan(@RequestBody Loan loan) {
        Loan regLoan = loanService.registerLoan(loan);
        if(regLoan == null) {
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity(HttpStatus.CREATED);
    }
}

Any ideas how to accomplish this goal?

UPDATE1:

ClientRepository:

@Repository
public interface ClientRepository extends JpaRepository<Client, Long>{
}

LoanRepository:

@Repository
public interface LoanRepository extends JpaRepository<Loan, Long> {
}

JSON to add client (works):

{
"id": 1,
"name": "Arthur",
"surname": "Doyle",
"phone": 777458642,
"email": "adoyle@imperial.com"
}

JSON to make a loan to specific client(fails):

{
    "id": 1,
    "client": "http://loacalhost:8080/api/clients/find/1",
    "startDate": 20170902,
    "originTerm": 20170902,
    "maxPossibleAmount": 5555.0000,
    "notes": null
}

回答1:


Your Loan is associated with Client. So if you want to create a loan for the client use this payload:

POST http://loacalhost:8080/api/loans 
{
    "originTerm": ...
    "maxPossibleAmount": ...
    "notes": ...
    "client": "http://loacalhost:8080/api/clients/1"
}

A custom controller is unnecessary.

P.S. Add @JsonIgnoreProperties("loans") to Loan.client to avoid the stackoverflow exception...

P.P.S. In @OneToMany the fetch parameter is FetchType.LAZY by default so you can avoid it.



来源:https://stackoverflow.com/questions/46022047/how-to-deal-with-onetomany-relation-in-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!