我在我的域模型中定义了两个实体Customer和SalesOrder,其中包含从customer到salesOrder的oneToMany关系。 以下代码删除销售订单:
SalesOrder salesOrder = salesOrderRepository.findByOrderNumber(orderNumber);
if(null != salesOrder){
Customer customer = salesOrder.getCustomer();
customer.setCurrentCredit(customer.getCurrentCredit() - salesOrder.getTotalPrice());
Iterator<SalesOrder> iter = customer.getSalesOrders().iterator();
while(iter.hasNext()){
SalesOrder order = iter.next();
if(order.getId().equals(salesOrder.getId())){
iter.remove();
break;
}
}
customerRepository.save(customer);
但以下代码不会删除销售订单。
SalesOrder salesOrder = salesOrderRepository.findByOrderNumber(orderNumber);
if(null != salesOrder){
Customer customer = salesOrder.getCustomer();
customer.setCurrentCredit(customer.getCurrentCredit() - salesOrder.getTotalPrice());
SalesOrder salesOrder = salesOrderRepository.findByOrderNumber(orderNumber);
if(null != salesOrder){
Customer customer = salesOrder.getCustomer();
customer.setCurrentCredit(customer.getCurrentCredit() - salesOrder.getTotalPrice());
salesOrderRepository.delete(salesOrder);
customerRepository.save(customer);
以下是域类: Customer.java
@Entity
@Table(name = "customer", uniqueConstraints = { @UniqueConstraint(columnNames = { "code" }) })
public class Customer extends BaseEntity {
@Column
private String code;
@Column
private String name;
@Column
private String address;
@Column
private String phone1;
@Column
private String phone2;
@Column
private Double creditLimit;
@Column
private Double currentCredit;
@OneToMany(cascade=CascadeType.ALL,mappedBy="customer",fetch=FetchType.LAZY,orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private List<SalesOrder> salesOrders = new ArrayList<SalesOrder>();
/**
* @return the code
*/
public String getCode() {
return code;
}
/**
* @param code the code to set
*/
public void setCode(String code) {
this.code = code;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the address
*/
public String getAddress() {
return address;
}
/**
* @param address the address to set
*/
public void setAddress(String address) {
this.address = address;
}
/**
* @return the phone1
*/
public String getPhone1() {
return phone1;
}
/**
* @param phone1 the phone1 to set
*/
public void setPhone1(String phone1) {
this.phone1 = phone1;
}
/**
* @return the phone2
*/
public String getPhone2() {
return phone2;
}
/**
* @param phone2 the phone2 to set
*/
public void setPhone2(String phone2) {
this.phone2 = phone2;
}
/**
* @return the creditLimit
*/
public Double getCreditLimit() {
return creditLimit;
}
/**
* @param creditLimit the creditLimit to set
*/
public void setCreditLimit(Double creditLimit) {
this.creditLimit = creditLimit;
}
/**
* @return the currentCredit
*/
public Double getCurrentCredit() {
return currentCredit;
}
/**
* @param currentCredit the currentCredit to set
*/
public void setCurrentCredit(Double currentCredit) {
this.currentCredit = currentCredit;
}
/**
* @return the salesOrders
*/
public List<SalesOrder> getSalesOrders() {
return salesOrders;
}
/**
* @param salesOrders the salesOrders to set
*/
public void setSalesOrders(List<SalesOrder> salesOrders) {
this.salesOrders = salesOrders;
}
}
SalesOrder.java
@Entity
@Table(name = "sales_order", uniqueConstraints = { @UniqueConstraint(columnNames = { "orderNumber" }) })
public class SalesOrder extends BaseEntity {
@Column
private String orderNumber;
@ManyToOne(cascade=CascadeType.DETACH, fetch=FetchType.LAZY)
@JoinColumn(name="customer_id",referencedColumnName="id")
private Customer customer;
@Column
private Double totalPrice;
@OneToMany(cascade=CascadeType.ALL,mappedBy="salesOrder",fetch=FetchType.LAZY,orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private List<OrderLines> orderLines= new ArrayList<OrderLines>();
/**
* @return the orderNumber
*/
public String getOrderNumber() {
return orderNumber;
}
/**
* @param orderNumber the orderNumber to set
*/
public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
/**
* @return the customer
*/
public Customer getCustomer() {
return customer;
}
/**
* @param customer the customer to set
*/
public void setCustomer(Customer customer) {
this.customer = customer;
}
/**
* @return the totalPrice
*/
public Double getTotalPrice() {
return totalPrice;
}
/**
* @param totalPrice the totalPrice to set
*/
public void setTotalPrice(Double totalPrice) {
this.totalPrice = totalPrice;
}
/**
* @return the orderLines
*/
public List<OrderLines> getOrderLines() {
return orderLines;
}
/**
* @param orderLines the orderLines to set
*/
public void setOrderLines(List<OrderLines> orderLines) {
this.orderLines = orderLines;
}
}
答案 0 :(得分:2)
请分享你的豆子。 鉴于你的描述,我希望你应该:
@Entity
@Table(name="CUSTOMER")
public class Customer implements Serializable {
private static final long serialVersionUID = -4505027246487844609L;
@Id
private String username;
@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true, fetch=FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
@JoinColumn(name="ORDER_USERNAME", nullable = false)
private List<SalesOrder> salesOrders;
}
重要的部分是:
@OneToMany(cascade=CascadeType.ALL, orphanRemoval=true, fetch=FetchType.EAGER)
fetchtype非常渴望,但也可能是懒惰的,没有关于如何获取链接实体数据的详细信息。 这应该可以解决问题,因此如果从父客户中删除销售,它将被删除。
在确认您的bean大致结构如下之后,我们可以继续分析您的问题。
UPDATE 如果bean的结构如此,那么行为的原因是明确的。 当您获取“客户”时,您已加载相关销售的集合... 现在..你在另一个对象中加载一个链接到该客户的销售,但是对象1(客户)和对象2(销售)现在完全分开了.. 结果是,当您删除object2时,您实际执行了删除,但随后您保存了客户(在列表对象中仍然存在对您删除的销售的引用),它将更新/插入与客户链接的所有销售基于客户bean。
您的情况是: 将Sales1和Sales2的客户提取到Object1中 Sales1进入Object2 删除Object2,它将删除不会改变Object1内容的sales1 ..,它仍然会有一个与sales1和sales2链接的cusotmer 保存Object1,您将更新客户(因为它已经存在),您将更新sales2(因为它已经存在)并插入sales1(因为您通过之前的删除删除了它)。 它将在同一笔交易中干净利落地处理..
现在..如果你想要实现你的结果,你可以在删除相关销售后“重新加载”(做另一个findOne或其他任何)bean客户,或者直接处理客户中包含的销售集合bean,以及从集合中删除这些对象并在完成时保存客户对象,而不涉及未链接到客户的辅助对象,这只会弄乱整个流程。
希望它有所帮助。