org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException:违反参照完整性约束
Posted
技术标签:
【中文标题】org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException:违反参照完整性约束【英文标题】:org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation 【发布时间】:2020-04-14 20:59:56 【问题描述】:春季启动 2.5
@Entity
public class Orders
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@NotNull
@DateTimeFormat(pattern = "dd.MM.yyyy HH:mm:ss")
private Date created;
private String paymentCardNumber;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "shipping_id")
private Shipping shipping;
private String promoCode;
@NotNull
private double totalAmount;
@NotNull
private String currenty;
@NotNull
@OneToMany(mappedBy = "orders", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<ProductEntry> productEntities = new HashSet<>();
public void addProduct(Product product, int quantity)
productEntities.add(new ProductEntry(product, quantity, this));
@Entity
public class ProductEntry
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Exclude
private int id;
@NotNull
@DateTimeFormat(pattern = "dd.MM.yyyy HH:mm:ss")
@Exclude
private Date created;
@DateTimeFormat(pattern = "dd.MM.yyyy HH:mm:ss")
@Exclude
private Date updated;
private int quantity;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Product product;
@Exclude
@ManyToOne(fetch = FetchType.LAZY)
private Orders orders;
@Exclude
@ManyToOne(fetch = FetchType.EAGER)
private Cart cart;@Entity
public class Product
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@NotNull
private String name;
private String description;
@NotNull
@DateTimeFormat(pattern = "dd.MM.yyyy HH:mm:ss")
private Date created;
@DateTimeFormat(pattern = "dd.MM.yyyy HH:mm:ss")
private Date updated;
@NotNull
private double price;
@NotNull
private String currency;
@ElementCollection
private Set<String> images;
@Exclude
@OneToOne(mappedBy = "product", fetch = FetchType.EAGER)
private ProductEntry productEntry;
我通过这种方法成功创建订单:
@PostMapping("/order/cart")
public Response createOrderByCart(@RequestBody Map<String, Object> payloadMap)
int cartId = (int) payloadMap.get("cart_id");
Optional<Cart> findCart = cartRepository.findById(cartId);
if (findCart.isPresent())
final Orders order = new ObjectMapper().convertValue(payloadMap.get("order"), Orders.class);
order.setCreated(new Date());
Cart cart = findCart.get();
Set<ProductEntry> productEntitiesInCartSet = cart.getProductEntities();
for (ProductEntry productEntry : productEntitiesInCartSet)
order.addProduct(productEntry.getProduct(), productEntry.getQuantity());
double orderTotalAmount = cart.getTotalAmount();
if (order.getPromoCode() != null && orderTotalAmount > PROMO_CODE_DISCOUNT_AMOUNT)
orderTotalAmount = orderTotalAmount - PROMO_CODE_DISCOUNT_AMOUNT;
order.setTotalAmount(orderTotalAmount);
order.setCurrenty(cart.getCurrency());
ordersRepository.save(order);
return ResponseService.getSuccessResponse(GsonUtil.gson.toJson(order));
else
String errorMessage = "Not found cart with id " + cartId;
logger.warn(errorMessage);
return ResponseService.getErrorResponse(errorMessage);
但在我尝试通过以下方式删除订单后:
@DeleteMapping("/orders")
public Response deleteAllOrders()
logger.info("deleteAllOrders: ");
ordersRepository.deleteAll();
logger.info("deleteAllOrders: success_delete_all_orders");
return ResponseService.getSuccessResponse();
我在这一行得到错误:
ordersRepository.deleteAll();
错误:
delete from product where id=? [23503-200]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKEWQ69R22L90CKJDKN8TTVB7J3: PUBLIC.PRODUCT_ENTRY FOREIGN KEY(PRODUCT_ID) REFERENCES PUBLIC.PRODUCT(ID) (3)"; SQL statement:
delete from product where id=? [23503-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:459) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.get(DbException.java:205) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.get(DbException.java:181) ~[h2-1.4.200.jar:1.4.200]
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:373) ~[h2-1.4.200.jar:1.4.200]
at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:390) ~[h2-1.4.200.jar:1.4.200]
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:265) ~[h2-1.4.200.jar:1.4.200]
at org.h2.table.Table.fireConstraints(Table.java:1057) ~[h2-1.4.200.jar:1.4.200]
at org.h2.table.Table.fireAfterRow(Table.java:1075) ~[h2-1.4.200.jar:1.4.200]
at org.h2.command.dml.Delete.update(Delete.java:153) ~[h2-1.4.200.jar:1.4.200]
at org.h2.command.CommandContainer.update(CommandContainer.java:198) ~[h2-1.4.200.jar:1.4.200]
at org.h2.command.Command.executeUpdate(Command.java:251) ~[h2-1.4.200.jar:1.4.200]
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:191) ~[h2-1.4.200.jar:1.4.200]
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:152) ~[h2-1.4.200.jar:1.4.200]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-3.4.2.jar:na]
【问题讨论】:
【参考方案1】:您正在删除所有Orders
。
由于CascadeType.ALL
,这也会删除订单的ProductEntry
。
这反过来又会触发删除相应的Product
。
这种情况一次发生一个Orders
。
当您遇到第一个引用 Product
的 Orders
实例时,该实例也被另一个 Order
引用,您会遇到约束冲突。
如果您确实想删除所有实体,请先删除所有 ProductEntry
实例并从那里级联(手动或使用 JPA),或者使用延迟约束(如果它们可用于您的数据库)。
如果级联配置实际上是一个错误,我认为这很可能,请将其修复为至少不包括删除操作。
【讨论】:
我需要 CascadeType.ALL,因为我还将许多产品添加到购物车。如果删除 CascadeType.ALL 则不会插入许多产品到购物车。 然后使用您实际需要的CascadeType
值。不止ALL
或者什么都没有。
这个帮助:cascade = CascadeType.PERSIST。谢谢以上是关于org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException:违反参照完整性约束的主要内容,如果未能解决你的问题,请参考以下文章