如何处理 REST 中的@OneToMany 关系
How to deal with @OneToMany relation in REST
我正在设计一个允许执行一些基本操作的小型 REST
应用程序。到目前为止一切顺利,我有以下 @Entity
称为 Client
需要与 @Entity
一起坚持称为 Loan
:
客户:
@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
}
贷款:
@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
}
通过邮递员注册客户完美无缺,但我不明白如何为特定客户注册贷款。尝试这样做时,PostMan
拒绝注册新贷款并显示以下消息:
{
"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"
}
贷款控制器:
@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);
}
}
有什么实现这个目标的想法吗?
更新1:
客户端存储库:
@Repository
public interface ClientRepository extends JpaRepository<Client, Long>{
}
贷款库:
@Repository
public interface LoanRepository extends JpaRepository<Loan, Long> {
}
JSON 添加客户端(有效):
{
"id": 1,
"name": "Arthur",
"surname": "Doyle",
"phone": 777458642,
"email": "adoyle@imperial.com"
}
JSON 向特定客户贷款(失败):
{
"id": 1,
"client": "http://loacalhost:8080/api/clients/find/1",
"startDate": 20170902,
"originTerm": 20170902,
"maxPossibleAmount": 5555.0000,
"notes": null
}
您的 Loan
与 Client
关联。因此,如果您想为客户创建贷款,请使用此有效负载:
POST http://loacalhost:8080/api/loans
{
"originTerm": ...
"maxPossibleAmount": ...
"notes": ...
"client": "http://loacalhost:8080/api/clients/1"
}
不需要自定义控制器。
P.S。将 @JsonIgnoreProperties("loans")
添加到 Loan.client
以避免 Whosebug 异常...
P.P.S。在 @OneToMany
中,fetch
参数默认为 FetchType.LAZY
,因此您可以避免它。
我正在设计一个允许执行一些基本操作的小型 REST
应用程序。到目前为止一切顺利,我有以下 @Entity
称为 Client
需要与 @Entity
一起坚持称为 Loan
:
客户:
@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
}
贷款:
@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
}
通过邮递员注册客户完美无缺,但我不明白如何为特定客户注册贷款。尝试这样做时,PostMan
拒绝注册新贷款并显示以下消息:
{ "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" }
贷款控制器:
@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);
}
}
有什么实现这个目标的想法吗?
更新1:
客户端存储库:
@Repository
public interface ClientRepository extends JpaRepository<Client, Long>{
}
贷款库:
@Repository
public interface LoanRepository extends JpaRepository<Loan, Long> {
}
JSON 添加客户端(有效):
{
"id": 1,
"name": "Arthur",
"surname": "Doyle",
"phone": 777458642,
"email": "adoyle@imperial.com"
}
JSON 向特定客户贷款(失败):
{
"id": 1,
"client": "http://loacalhost:8080/api/clients/find/1",
"startDate": 20170902,
"originTerm": 20170902,
"maxPossibleAmount": 5555.0000,
"notes": null
}
您的 Loan
与 Client
关联。因此,如果您想为客户创建贷款,请使用此有效负载:
POST http://loacalhost:8080/api/loans
{
"originTerm": ...
"maxPossibleAmount": ...
"notes": ...
"client": "http://loacalhost:8080/api/clients/1"
}
不需要自定义控制器。
P.S。将 @JsonIgnoreProperties("loans")
添加到 Loan.client
以避免 Whosebug 异常...
P.P.S。在 @OneToMany
中,fetch
参数默认为 FetchType.LAZY
,因此您可以避免它。