尝试保存包含产品列表的订单

问题描述 投票:0回答:1

我正在构建一个电子商务 API,但现在我面临一个问题,我无法保存我的订单必须包含的产品列表。

我不知道我在实体之间使用的关系还是其他东西,但它们是:

订购

@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@ManyToOne
@JoinColumn(name = "client_id", referencedColumnName = "cpf")
private Client client;

@OneToMany(mappedBy = "order")
private List<OrderProduct> products = new ArrayList<>();

@Column(name = "total")
private double total;

@Column(name = "status")
private StatusEnum status;

@Column(name = "createdAt")
private LocalDate createdAt;

public Order() {}
}

订购产品

@Entity
@Table(name = "order_products")
public class OrderProduct implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id")
private Order order;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id")
private Product product;

@Column(name = "quantity")
private int quantity;

public OrderProduct(Order order, Product product, Integer quantity) {
    this.order = order;
    this.product = product;
    this.quantity = quantity;
}

public double getTotalPrice() {
    return this.product.getPrice() * this.quantity;
 }
}

这是创建订单的服务方法

public Order create(OrderDTO orderObj) {
    Client orderClient = clientService.get(orderObj.getClient());
    Order order = new Order();
    order.setCreatedAt(LocalDate.now());
    order.setProducts(this.getOrderProducts(order, orderObj.getProducts()));
    order.setClient(orderClient);
    order.setTotal(this.getOrderTotal(order));
    order.setStatus(StatusEnum.PROCESSING);

    return orderRepository.save(order);
}

private List<OrderProduct> getOrderProducts(Order order, Map<Long, Integer> productsObj) {
    List<OrderProduct> products = new ArrayList<>();
    for (Map.Entry<Long, Integer> entry : productsObj.entrySet()) {
        Product product = productService.updateProductStock(entry.getKey(), entry.getValue(), true);
        products.add(new OrderProduct(order, product, entry.getValue()));
    }
    return products;
}
java postgresql spring-boot hibernate jpa
1个回答
0
投票

看来您在建立实体之间的关系方面走在正确的轨道上。然而,需要理解的一件重要的事情是,在双向关系中,您需要考虑双方。

保存

Order
时,不会自动保存与其关联的
OrderProduct
。这和JPA中的
CascadeType
有关。如果你想同时保存
Order
OrderProducts
,你应该这样做:

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderProduct> products = new ArrayList<>();

这里,

CascadeType.ALL
表示在
Order
上执行的所有操作(持久、合并、刷新、删除和分离)也将在
OrderProduct
上执行。

但是,在这种情况下,简单添加级联类型可能还不够。问题的出现是由于 Hibernate 如何管理实体状态。当一个新的

OrderProduct
添加到
Order
时,Hibernate 并不知道它,因为当您向其添加新的
Order
时,
OrderProducts
处于分离状态(在
getOrderProducts()
方法中)。

为了解决这个问题,我们需要确保关系的双方都正确更新。这通常涉及以下步骤:

  • 在您的
    OrderProduct
    实体中,在构造函数的末尾添加
    order.addProduct(this);

Order
实体中:

public void addProduct(OrderProduct product){
    products.add(product);
    product.setOrder(this);
}

通过这种方式,可以双向管理关系,Hibernate 将了解该关系并继续对

cascade
设置采取行动。

© www.soinside.com 2019 - 2024. All rights reserved.