簡體   English   中英

使用 JPA 在春季使用級聯刪除

[英]Delete with cascade in spring with JPA

我正在開發超市產品的配送系統。 我有包含項目列表的訂單。 每個項目都包含一個產品。 我正在嘗試刪除產品,我正在通過在我的產品實體中設置標志來執行邏輯刪除。 但是我必須刪除屬於產品的商品,並重新計算訂單的價格並更新其商品。

這是我的代碼

訂單.java

@Entity
@Table (name="Orders")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column (name = "id", nullable = false)
    private long id;
    @OneToMany( mappedBy = "order", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.EAGER)
    @JsonIgnore
    private List<Item> items;

    private float totalPrice;
}

項目.java

@Entity
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;
    
    @OneToOne( fetch = FetchType.EAGER)
    @JoinColumn( name="id_order" )
    private Order order;

    @OneToOne( fetch = FetchType.EAGER)
    @JoinColumn( name="id_product" )
    private Product product;

    private boolean active;

}

產品控制器.java

@DeleteMapping("/remover-producto/{product_id}")
@ResponseStatus(HttpStatus.OK)
public void removerProducto(@PathVariable long product_id) {
    Optional<Product> productToRemove = productService.findProduct(product_id);
    // Get the product to remove
    if(productToRemove.isPresent()) {
        // Perform logical deletion
        productToRemove.get().setActive(false);
        // Update entity with flag
        productService.eliminarLogico(productToRemove.get());
        // get item from the product_id
        Optional<Item> itemToRemove = itemService.itemWithProductId(product_id);
        if(itemToRemove.isPresent()) {
            // physical removal of item
            orderService.removeItemFromOrderAndUpdatePrice(itemToRemove.get());
        }
    }
}

OrderServiceImpl.java

@Override
    public void removeItemFromOrderAndUpdatePrice(Item item) {
        // get order that contains the item
        Optional<Order> orderToUpdate = orderRepository.findOrderWithItemId(item.getId());

        if(orderToUpdate.isPresent()) {
            // update total price from order
            float total = orderToUpdate.get().getTotalPrice() - item.getProduct().getPrice();
            orderToUpdate.get().setTotalPrice(total);
            // filter to remove item from order items
            List<Item> updatedItems = orderToUpdate.get().getItems()
                    .stream()
                    .filter(oldItem -> oldItem.getId() != item.getId())
                    .collect(Collectors.toList());
           
            orderToUpdate.get().getItems().clear();
            orderToUpdate.get().setItems(updatedItems);
            // It is not updating with the new list of items.
            orderRepository.save(orderToUpdate.get());
        }
    }

我按照級聯類型持久化和刪除的順序定義了項目列表。 但該項目仍在數據庫中。 產品已成功刪除(邏輯上)並且訂單具有正確的總價。

我嘗試添加orphanRemoval=true但我得到 --> 擁有實體實例不再引用具有 cascade="all-delete-orphan" 的集合:com.bd.tpfinal.model.Order.items

你的映射不正確嗎? 我想應該是ManyToOne的關系

@Entity
public class Item {
  
  ...

  @ManyToOne( fetch = FetchType.EAGER)
  @JoinColumn( name="id_order" )
  private Order order;

  ...

}

此方法與您想要做的完全相反。它返回一個包含您要刪除的項目的列表,並且不刪除該項目

  // filter to remove item from order items
        List<Item> updatedItems = orderToUpdate.get().getItems()
                .stream()
                .filter(oldItem -> oldItem.getId() == item.getId())
                .collect(Collectors.toList());

為了從列表中刪除項目,您必須過濾並選擇 ID 不等於項目 ID 的所有項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM