【发布时间】:2021-06-03 14:30:56
【问题描述】:
我有以下三个实体类:
发货实体:
@Entity
@Table(name = "SHIPMENT")
public class Shipment implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "SHIPMENT_ID", nullable = false)
private int shipmentId;
@Column(name = "DESTINATION", nullable = false)
private String destination;
@OneToMany(mappedBy = "shipment")
private List<ShipmentDetail> shipmentDetailList;
//bunch of other variables omitted
public Shipment(String destination) {
this.destination = destination;
shipmentDetailList = new ArrayList<>();
}
发货详情实体:
@Entity
@Table(name = "SHIPMENT_DETAIL")
public class ShipmentDetail implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "SHIPMENT_DETAIL_ID", nullable = false)
private int shipmentDetailId;
@ManyToOne
@JoinColumn(name = "PRODUCT_ID", nullable = false)
private Product product;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "SHIPMENT_ID", nullable = false)
private Shipment shipment;
//bunch of other variables omitted
public ShipmentDetail() {
}
public ShipmentDetail(Shipment shipment, Product product) {
this.product = product;
this.shipment = shipment;
}
产品实体:
@Entity
@Table(name = "Product")
public class Product implements Serializable {
@Id
@Column(name = "PRODUCT_ID", nullable = false)
private String productId;
@Column(name = "PRODUCT_NAME", nullable = false)
private String productName;
//bunch of other variables omitted
public Product() {
}
public Product(String productId, String productName) {
this.productId = productId;
this.productName = productName;
}
我正在通过 REST API 接收 JSON。问题是我不知道如何使用仅通过 ID 与现有对象有关系的 shippingDetails 反序列化新 Shipment。我知道您可以简单地使用 objectmapper 进行反序列化,但这需要 product 的所有字段都在每个 shippingDetail 中。如何仅使用 productID 进行实例化?
收到的 JSON 样本
{
"destination": "sample Dest",
"shipmentDetails": [
{
"productId": "F111111111111111"
},
{
"productId": "F222222222222222"
}
]
}
目前我的休息端点将接收 JSON,然后执行以下操作:
public ResponseEntity<String> test(@RequestBody String jsonString) throws JsonProcessingException {
JsonNode node = objectMapper.readTree(jsonString);
String destination = node.get("destination").asText();
Shipment newShipment = new Shipment(destination);
shipmentRepository.save(newShipment);
JsonNode shipmentDetailsArray = node.get("shipmentDetails");
int shipmentDetailsArrayLength = shipmentDetailsArray.size();
for (int c = 0; c < shipmentDetailsArrayLength; c++) {
String productId = node.get("productId").asText();
Product product = productRepository.findById(productId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "No product with ID of: " + productId + " exists!"));
ShipmentDetail shipmentDetail = new ShipmentDetail(newShipment, product, quantity);
shipmentDetailRepository.save(shipmentDetail);
}
}
我想做的是:
public ResponseEntity<String> test2(@RequestBody String jsonString) throws JsonProcessingException {
JsonNode wholeJson = objectMapper.readTree(jsonString);
Shipment newShipment = objectMapper.treeToValue(wholeJson, Shipment.class);
return new ResponseEntity<>("Transfer Shipment successfully created", HttpStatus.OK);
}
我试过这个解决方案没有。利用: Deserialize with Jackson with reference to an existing object
如何让产品实体搜索现有产品,而不是尝试创建新产品。我一直在使用的 hacky 极其低效的解决方法是遍历 json 数组,并为每个 productId 使用 productRepository 找到产品,然后将 shippingDetail 与产品一一设置。我不确定这是否是我自学春季的最佳实践。
所以在伪代码中我想要做的是:
- 接收 JSON
- 实例化发货实体
- 实例化一系列 shippingDetail 实体 每批货物详情: 1. 查找具有给定 productId 的产品 2. 用 product 和 shipping 实例化 shippingDetail
代码已大大简化,以更好地展示问题,
【问题讨论】:
标签: java json spring jackson deserialization