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.