Search code examples
javaspringspring-boothibernatespring-data-jpa

Why Json Deserialization cause problems with BaseJpaRepository?


Edit: By @Mar-z suggestion I have updated the code but it now has another problem, which is still related to same functionality.

My items list is always empty with a a payload like this one:

{
  "orderId": 1,
  "items": [
    {
      "itemId": 3,
      "itemName": "Product A",
      "quantity": 2,
      "price": 10.99
    },
    {
      "itemId": 4,
      "itemName": "Product B",
      "quantity": 1,
      "price": 19.99
    }
  ],
  "status": "PROCESSING"
}

I have 2 entity classes defined as here:

@Entity
public class OrderItem {

    @Id
    private Long itemId;
    private String itemName;
    private  int quantity;
    private double price;

    @ManyToOne
    @JoinColumn(name = "parent_order_id")
    private Order order;

    public OrderItem () {

    }
    public OrderItem(Long itemId, String itemName, int quantity, double price) {
        this.itemId = itemId;
        this.itemName = itemName;
        this.quantity = quantity;
        this.price = price;
    }

@Entity
@Table(name = "`order`")
public class Order {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long orderId;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<OrderItem> items;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;

    public Order() {
        this.items = new ArrayList<>();
    }
    public Order(Long orderId, List<OrderItem> items, OrderStatus status) {
        this.orderId = orderId;
        this.items = items;
        this.status = status;
    }


    public Order createOrder(Order newOrder) {
        return orderRepository.merge(newOrder);
    }

EDITED: The issue is my response is always like this:

{
    "orderId": 1,
    "items": [
        {
            "itemId": 103,
            "itemName": "Product A",
            "quantity": 2,
            "price": 10.99,
            "order": null
        },
        {
            "itemId": 104,
            "itemName": "Product B",
            "quantity": 1,
            "price": 19.99,
            "order": null
        }
    ],
    "status": "PROCESSING"
}

As you can see my order is null and in database my parent_order_id is also null.

I use the repository class defined here but after soem trial and error i came to conclision it si not the problem: https://vladmihalcea.com/basejparepository-hypersistence-utils/


Solution

  • It is a bi-directional relationship. You must set the reference in the OrderItem entity programmatically. For example by adding a loop in the service method createOrder():

    public Order createOrder(Order newOrder) {
        for (OrderItem item : newOrder.getItems()) {
            item.setOrder(newOrder);
        }
        return orderRepository.save(newOrder);
    }
    

    Be aware of possible infinite loop. Use @JsonManagedReference and @JsonBackReference annotations in the entities to avoid it.

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JsonManagedReference
    private List<OrderItem> items;
    // ...
    @ManyToOne
    @JsonBackReference
    @JoinColumn(name = "parent_order_id")
    private Order order;