我有两个表,其中一个表对另一个表的主键有外键约束。 我需要执行一个事务,我需要在两个表中插入一个条目并仅在两个条目都成功时提交事务,否则回滚整个事务,
但由于第二个表中存在外键约束,并且第一个表中的条目尚未提交,因此无法执行第二个表的插入。
表结构如下:
orderMaster
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| OID | varchar(255) | NO | PRI | NULL | |
| CUSTOMER | varchar(255) | YES | MUL | NULL | |
| DATE | datetime | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
ORDERDETAILS
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| ID | int(11) | NO | PRI | NULL | |
| OID | varchar(255) | YES | MUL | NULL | |
| ITEM | varchar(255) | YES | MUL | NULL | |
| QUANT | int(11) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
这里orderDetails表中的OID字段是orderMaster表中的外键。
我使用hibernate as
将条目保存到表中try{
transaction.begin();
session.save(orderMaster);
boolean status=false;
OrderDetailsDAO odao= new OrderDetailsDAO();
System.out.println(orderDetails.size());
for(OrderDetails od: orderDetails){
status=odao.saveOrder(od);
if(!status)
break;
}
if(!status){
txn.rollback();
return false;
}
else{
txn.commit();
return true;
}
}catch(HibernateException ex){
ex.printStackTrace();
if(txn!=null)
txn.rollback();
return false;
}
我的堆栈跟踪如下:
java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`cart`.`orderdetails`, CONSTRAINT `FKB8CC1F34C5FC9376` FOREIGN KEY (`OID`) REFERENCES `ordermaster` (`OID`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1669)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1085)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 37 more
我如何插入两个表?
如果在两个表上都完成了完整的条目,那么只有交易才能提交,否则就会发生回滚。
答案 0 :(得分:0)
除非您引入了循环依赖,否则这不会有问题。在插入与其运行的行之前,请确保满足外键依赖性。您可以在错误列中插入具有NULL值的行,然后在处理外部引用器之后,将NULL值更新为重要的FK参考值。
答案 1 :(得分:0)
好像你没有设置orderDetails.OID
。
session.save(orderMaster)
orderMaster.OID
orderDetails.OID
设为该值