简体   繁体   English

使用 JPA 在春季使用级联删除

[英]Delete with cascade in spring with JPA

I'm developing a delivery system for supermarket products.我正在开发超市产品的配送系统。 I have Orders which contain a list of items.我有包含项目列表的订单。 Each item contains a product.每个项目都包含一个产品。 I'm trying to delete a product, I'm performing a logic deletion by setting a flag in my product entity.我正在尝试删除产品,我正在通过在我的产品实体中设置标志来执行逻辑删除。 But I have to remove the item which belongs to a product and also recalculate the price of the order and update its items.但是我必须删除属于产品的商品,并重新计算订单的价格并更新其商品。

Here's my code这是我的代码

Order.java订单.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;
}

Item.java项目.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;

}

ProductController.java产品控制器.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 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());
        }
    }

I defined the list of items in order with cascade type persist and remove.我按照级联类型持久化和删除的顺序定义了项目列表。 But the item is still in the database.但该项目仍在数据库中。 The product is successfully deleted (logically) and the order has the correct total price.产品已成功删除(逻辑上)并且订单具有正确的总价。

I tried adding orphanRemoval=true but I get --> A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.bd.tpfinal.model.Order.items我尝试添加orphanRemoval=true但我得到 --> 拥有实体实例不再引用具有 cascade="all-delete-orphan" 的集合:com.bd.tpfinal.model.Order.items

isn't your mapping incorrect?你的映射不正确吗? I guess it should be a ManyToOne relationship我想应该是ManyToOne的关系

@Entity
public class Item {
  
  ...

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

  ...

} }

This method does the exact opposite of what u want to do.It returns a list with the item you want to remove and does not remove the item此方法与您想要做的完全相反。它返回一个包含您要删除的项目的列表,并且不删除该项目

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

in order to remove item from the list you have to filter and select all items whose id is not equal to item id.为了从列表中删除项目,您必须过滤并选择 ID 不等于项目 ID 的所有项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM