Hibernate 在同一事务中更新父级时休眠删除子级
我在我的域模型中定义了两个实体Customer和SalesOrder,其中Customer和SalesOrder之间有一对一的关系。 以下代码删除销售订单:Hibernate 在同一事务中更新父级时休眠删除子级,hibernate,spring-data,Hibernate,Spring Data,我在我的域模型中定义了两个实体Customer和SalesOrder,其中Customer和SalesOrder之间有一对一的关系。 以下代码删除销售订单: SalesOrder salesOrder = salesOrderRepository.findByOrderNumber(orderNumber); if(null != salesOrder){ Customer customer = salesOrder.getCustomer(); customer
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);
以下是域类:
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;
}
}
@实体
@表(name=“customer”,uniqueConstraints={@UniqueConstraint(columnNames={“code”})})
公共类客户扩展BaseEntity{
@纵队
私有字符串码;
@纵队
私有字符串名称;
@纵队
私有字符串地址;
@纵队
私有字符串phone1;
@纵队
私有字符串phone2;
@纵队
私人双重信贷限额;
@纵队
私人双重信用;
@OneToMany(cascade=CascadeType.ALL,mappedBy=“customer”,fetch=FetchType.LAZY,orphan=true)
@LazyCollection(LazyCollectionOption.FALSE)
private List salesOrders=new ArrayList();
/**
*@返回代码
*/
公共字符串getCode(){
返回码;
}
/**
*@param code要设置的代码
*/
公共无效设置码(字符串码){
this.code=代码;
}
/**
*@返回名称
*/
公共字符串getName(){
返回名称;
}
/**
*@param name要设置的名称
*/
公共void集合名(字符串名){
this.name=名称;
}
/**
*@返回地址
*/
公共字符串getAddress(){
回信地址;
}
/**
*@param address要设置的地址
*/
公共无效设置地址(字符串地址){
this.address=地址;
}
/**
*@返回电话1
*/
公共字符串getPhone1(){
返回电话1;
}
/**
*@param phone1要设置的phone1
*/
公共void setPhone1(字符串phone1){
this.phone1=phone1;
}
/**
*@返回电话2
*/
公共字符串getPhone2(){
返回电话2;
}
/**
*@param phone2要设置的phone2
*/
公共void setPhone2(字符串phone2){
this.phone2=phone2;
}
/**
*@返回信用额度
*/
公共双getCreditLimit(){
退货限额;
}
/**
*@param creditLimit要设置的creditLimit
*/
公共无效设置信用额度(双重信用额度){
this.creditLimit=creditLimit;
}
/**
*@返回当前信用卡
*/
公共双getCurrentCredit(){
返回当前信用;
}
/**
*@param currentCredit要设置的currentCredit
*/
公共无效setCurrentCredit(双倍currentCredit){
this.currentCredit=currentCredit;
}
/**
*@退回销售订单
*/
公共列表getSalesOrders(){
退回销售订单;
}
/**
*@param salesforders要设置的salesforders
*/
公共销售订单(列出销售订单){
this.salesforders=销售订单;
}
}
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;
}
}
@实体
@表(name=“sales_order”,uniqueConstraints={@UniqueConstraint(columnNames={“orderNumber”})})
公共类SalesOrder扩展了BaseEntity{
@纵队
私有字符串orderNumber;
@manytone(cascade=CascadeType.DETACH,fetch=FetchType.LAZY)
@JoinColumn(name=“customer\u id”,referencedColumnName=“id”)
私人客户;
@纵队
私人双总价;
@OneToMany(cascade=CascadeType.ALL,mappedBy=“salesOrder”,fetch=FetchType.LAZY,orphan=true)
@LazyCollection(LazyCollectionOption.FALSE)
private List orderLines=new ArrayList();
/**
*@返回订单号
*/
公共字符串getOrderNumber(){
退货订单号;
}
/**
*@param orderNumber要设置的订单号
*/
公共无效setOrderNumber(字符串orderNumber){
this.orderNumber=订单号;
}
/**
*@退回客户
*/
公共客户getCustomer(){
退货客户;
}
/**
*@param customer要设置的客户
*/
公共作废设置客户(客户){
this.customer=customer;
}
/**
*@返回总价
*/
公共双getTotalPrice(){
返回总价;
}
/**
*@param totalPrice要设置的总价
*/
公共无效设置总价(双倍总价){
this.totalPrice=totalPrice;
}
/**
*@返回订单行
*/
公共列表getOrderLines(){
退货订单行;
}
/**
*@param医嘱行要设置的医嘱行
*/
公共无效集合医嘱行(列出医嘱行){
this.orderLines=订单行;
}
}
请分享您的bean。
根据您的描述,我认为您应该:
@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;
}
fetchtype是急切的,但也可能是懒惰的,没有关于如何获取链接实体数据的详细信息。
这应该可以做到这一点,因此,如果您从父客户删除销售,它将被删除
在您确认bean的结构大致如下之后,我们可以继续分析您的问题
更新如果bean是这样构造的,那么行为的原因就很清楚了。。
当您获取“客户”时,您已加载相关销售的集合。。。
现在。。您在另一个对象中加载了一个链接到该客户的销售,但是object1(客户)和object2(销售)现在完全分开了。。
结果是,当您删除object2时,实际上执行了删除操作,但随后保存了customer(在列表对象中仍然存在对您删除的销售的引用),它将根据customer bean更新/插入链接到该客户的所有销售
你的情况是:
将Sales1和Sales2提取到Object1中的客户
Sales1已进入Object2
删除Object2,它将删除sales1。。这不会改变Object1的内容,它仍然有一个与sales1和sales2链接的cusotmer
保存Object1时,您将更新customer(因为它已经存在),更新sales2(因为它已经存在)并插入sales1(因为您通过上一次删除将其删除)。
在同一笔交易中,所有这些都将得到干净的处理
现在。。如果您想要实现您的结果,您可以在删除相关销售后“重新加载”(执行另一个findOne或其他操作)bean客户,或者直接处理customer bean中包含的销售集合,并在完成后从集合中删除这些对象并保存customer对象,不涉及未链接到客户的次要对象,只会扰乱整个流程
希望有帮助。Pl
@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)