删除一对多关系中的父项会抛出 MySQLIntegrityConstraintViolationException
Deleting the parent in a one-to-many relationship throws MySQLIntegrityConstraintViolationException
我有一个经典的一对多情况。一车,多件。
@Entity
@Table(name="CART")
public class Cart {
//...
@OneToMany(fetch = FetchType.LAZY, mappedBy="cart")
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE })
private Set<Items> items;
// getters and setters
}
需要特别注意的是 CascadeType.SAVE_UPDATE,
@Entity
@Table(name="ITEMS")
public class Items {
//...
@ManyToOne
private Cart cart;
public Items() {}
// getters and setters
}
我要实现的行为:
- 购物车得到更新或保存,项目应该得到更新或保存。
- 购物车被删除,商品应该不被删除。 (这些项目有自己的生命周期。)
- 购物车被删除,项目 table 的外键应设置为空。
在当前的实施中,最后一点没有发生。 运行 代码和删除购物车导致:
MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails ...
对于此类情况,推荐的休眠解决方案是什么?
尝试这样的事情:
Transaction transaction = session.beginTransaction();
items.setCart(null);
session.update(items);
session.delete(cart);
transaction1.commit();
您应该在删除购物车之前将商品的购物车属性设置为 null
:
Cart cartToDel = cartRepository.getOne(1l);
cartToDel.getItems().forEach(item -> item.setCart(null));
cartRepository.delete(cartToDel);
我有一个经典的一对多情况。一车,多件。
@Entity
@Table(name="CART")
public class Cart {
//...
@OneToMany(fetch = FetchType.LAZY, mappedBy="cart")
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE })
private Set<Items> items;
// getters and setters
}
需要特别注意的是 CascadeType.SAVE_UPDATE,
@Entity
@Table(name="ITEMS")
public class Items {
//...
@ManyToOne
private Cart cart;
public Items() {}
// getters and setters
}
我要实现的行为:
- 购物车得到更新或保存,项目应该得到更新或保存。
- 购物车被删除,商品应该不被删除。 (这些项目有自己的生命周期。)
- 购物车被删除,项目 table 的外键应设置为空。
在当前的实施中,最后一点没有发生。 运行 代码和删除购物车导致:
MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails ...
对于此类情况,推荐的休眠解决方案是什么?
尝试这样的事情:
Transaction transaction = session.beginTransaction();
items.setCart(null);
session.update(items);
session.delete(cart);
transaction1.commit();
您应该在删除购物车之前将商品的购物车属性设置为 null
:
Cart cartToDel = cartRepository.getOne(1l);
cartToDel.getItems().forEach(item -> item.setCart(null));
cartRepository.delete(cartToDel);