问题
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