I am developing online store app and I'm struggling with purchase system. Generally I need to write service which works with steps:
- Check whether customer has sufficient funds for payment
- If he does - subtract amount of product's cost from
Customer
's balance - Delete
Product
fromCustomer
collection (this doesn't work!) - Save
Customer
with updated collection to database - Delete
Product
from database
However, no matter how I try to do this, Product
is not deleted from Customer
collection. remove()
method, clear()
method, etc., nothing works. Every time I log Customer
collection to console after purchase, purchased Product
still belongs to Customer
who posted Product
. This major problem causes many bugs which - for example - regard saving Customer
with non-existing Product
(since in next purchase, saving Customer
includes non-deleted previous Product
in Customer
collection).
Snippets of code:
Piece of Service:
public boolean processPayment(Customer customerToEdit, Product productToOperate) {
if (customerToEdit.getBalance() >= productToOperate.getProductCost())
{
Customer retrievedProductOwner = productToOperate.getProductOwner();
customerToEdit.setBalance(customerToEdit.getBalance()-productToOperate.getProductCost());
/* This doesn't execute! */
retrievedProductOwner.getOwnedProducts().remove(productToOperate);
customerDAO.save(retrievedProductOwner);
}
else {
System.out.println("Insufficient funds!");
return false;
}
return true;
}
Piece of Controller:
@GetMapping("/showOffer")
public String getOffer(@RequestParam("offerId") int offerId, Model theModel, @AuthenticationPrincipal MyUserDetails user) {
Product retrievedProduct = productService.findById(offerId);
if (customerService.processPayment(user.getCustomer(), retrievedProduct)) {
productService.delete(retrievedProduct.getId());
}
return "redirect:/home";
}
Product.java:
@Entity
@Table(name="product")
public class Product {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="name")
private String productName;
@Column(name="description")
private String productDescription;
@Column(name="category")
private String productCategory;
@Column(name="cost")
private int productCost;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="owner_id")
private Customer productOwner;
/* (...) */
Customer.java:
@Entity
@Table(name="customer")
public class Customer {
//Class fields
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="balance")
private int balance;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="email")
private String email;
@OneToMany(mappedBy="productOwner", fetch=FetchType.EAGER)
private List<Product> ownedProducts;
/* (...) */
CodePudding user response:
You need to enable orphan removal of products by adding CascadeType.PERSIST and orphan removal true
@OneToMany(mappedBy = "productOwner", fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<Product> ownedProducts = new ArrayList<>();
When you save the customer this should trigger delete of the removed Product