我正在使用 Spring Boot 和 JPA 编写 REST 服务。我在带有复合键的表中有一对多映射。假设如果父表“订单”有 2 个复合键(订单 id、销售日期),并且“订单详细信息”有该订单的多个项目和 3 个复合键(订单 id、销售日期和项目 id),我的请求对象应该如何是。我想知道是否可以不显式设置连接列属性并保留对象;就像我想发送以下 POST 有效负载并将其映射到 Order 对象。此映射不会设置 salesDate 和 orderId 的值,它们是 OrderDetail 的组合键。因此,由于重复而导致持久失败。
{
"salesDate": "2016-02-12",
"orderId": 12,
"Description":"Sample order",
"orderDetail":[{
"itemId": 1231,
"quantity": 2
},
{
"itemId": 23342,
"quantity": 1
}]
}
订单.java:
@Entity
@Table(name = "ORDR")
@IdClass(OrderId.class)
public class Order implements Serializable {
private static final long serialVersionUID = 2496620945369260577L;
@Id
@Column(name = "SLS_DT")
private Date salesDate;
@Id
@Column(name = "ORDR_ID")
private int orderId;
@Column(name = "ORDR_DESC")
private short orderDescription;
@Column(name = "CUST_ID")
private int customerId;
@OneToMany(cascade= CascadeType.ALL, mappedBy = "order")
private List<OrderDetail> orderItems;
public Date getSalesDate() {
return salesDate;
}
public void setSalesDate(Date salesDate) {
this.salesDate = salesDate;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public short getOrderDescription() {
return orderDescription;
}
public void setOrderDescription(short orderDescription) {
this.orderDescription = orderDescription;
}
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
}
OrderId.java:
public class OrderId {
private Date salesDate;
private int orderId;
public Date getSalesDate() {
return salesDate;
}
public void setSalesDate(Date salesDate) {
this.salesDate = salesDate;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
}
订单明细.java
@Entity
@Table(name= "ORDR_DTL")
@IdClass(OrderDetail.class)
public class OrderDetail implements Serializable{
private static final long serialVersionUID = 3603127094767197954L;
@Id
@Column(name = "SLS_DT")
private Date salesDate;
@Id
@Column(name = "ORDR_ID")
private int orderId;
@Id
@Column(name = "ITEM_ID")
private int itemId;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumns({@JoinColumn(name = "SLS_DT", referencedColumnName = "SLS_DT", insertable = false, updatable = false),
@JoinColumn(name = "ORDR_ID", referencedColumnName = "ORDR_ID", insertable = false, updatable = false)})
private Order order;
private BigDecimal quantity;
public Date getSalesDate() {
return salesDate;
}
public void setSalesDate(Date salesDate) {
this.salesDate = salesDate;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
public BigDecimal getQuantity() {
return quantity;
}
public void setQuantity(BigDecimal quantity) {
this.quantity = quantity;
}
}
OrderDetailId.java:
public class OrderDetailId implements Serializable {
private static final long serialVersionUID = 2312835624801595602L;
private Date salesDate;
private int orderId;
public Date getSalesDate() {
return salesDate;
}
public void setSalesDate(Date salesDate) {
this.salesDate = salesDate;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
private int itemId;
}
如果我传递以下 JSON,它会按预期工作。但我不想重复订单详细信息中的键,也不想将数据库结构暴露给客户端。
{
"salesDate": "2016-02-12",
"orderId": 12,
"Description": "Sample order",
"orderDetail": [{
"salesDate": "2016-02-12",
"orderId": 12,
"itemId": 1231,
"quantity": 2
}, {
"salesDate": "2016-02-12",
"orderId": 12,
"itemId": 23342,
"quantity": 1
}]
}
我可以传递第一个 json 并将其转换为 JPA 实体。但我相信应该有一种更清洁的方法。 JPA 文档对于这种情况没有多大帮助。请帮我解决这个问题。
您可以尝试在
@JsonIgnore
的 orderId
成员上使用 OrderDetailId
注释。这应该会抑制 JSON 输出中的成员。
@JsonIgnore
private int orderId;
还有类注释
@JsonIgnoreProperties({"memberName"})
。您不必在类源代码“内部”标记每个成员。
@JsonIgnoreProperties({"orderId"})
public class OrderDetail implements Serializable {
...