Home > other >  Delete with cascade in spring with JPA
Delete with cascade in spring with JPA

Time:06-09

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

@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

@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

@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());
        }
    }

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

CodePudding user response:

isn't your mapping incorrect? I guess it should be a ManyToOne relationship

@Entity
public class Item {
  
  ...

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

  ...

}

CodePudding user response:

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.

  • Related