I have three entity classes of the following:
Shipments Entity:
@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<>();
}
Shipment Details Entity:
@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;
}
Product Entity:
@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;
}
I am receiving JSONs through a rest API. The problem is I do not know how to deserialize a new Shipment with shipmentDetails that have relationships to already existing objects just by ID. I know you can simply deserialize with the objectmapper, but that requires all the fields of product to be in each shipmentDetail. How do i instantiate with just the productID?
Sample JSON received
{
"destination": "sample Dest",
"shipmentDetails": [
{
"productId": "F111111111111111"
},
{
"productId": "F222222222222222"
}
]
}
Currently my rest endpoint would then receive the JSON, and do this:
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);
}
}
what i want to do is:
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);
}
I tried this solution to no. avail: Deserialize with Jackson with reference to an existing object
How do I make the product entity search for an existing product instead of trying to create a new product. The hacky extremely inefficient workaround I have been using is to traverse the json array, and for every productId find the product using the productRepository, and then set the shipmentDetail with the product one by one. Im not sure if this is best practice as im self learning spring.
So in pseudocode what im trying to do would be:
- Receive JSON
- Instantiate Shipment entity
- Instantiate an array of shipmentDetail entities For each shipmentDetail: 1. Find product with given productId 2. Instantiate shipmentDetail with product and shipment
Code has been significantly simplified to better showcase the problem,