错误: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
java.sql.BatchUpdateException: Duplicate entry '24-0-es_reservation_detail' for key 'questionId_referenceId_referenceType'
我要保存预订对象 . 此预留对象包含reservaitonDetails对象的集合,每个预留详细信息对象包含questionAnswers对象的集合 .
主要问题是对questionAnswer表的唯一约束
Unqiue Constraint: question_id, reference_id, reference_type.
当系统保存预约对象时:系统首先保存预约,然后收集预订详细信息,然后用0(reference_id)查询所有问题答案 . 在添加带有0引用id的问题时,系统会抛出异常,因为违反了唯一约束 .
ReservationDetail.hbm.xml
.............
.............
<set name="questionAnswers" lazy="true" cascade="all-delete-orphan" where="reference_type = 'es_reservation_detail'">
<key column="reference_id"/>
<one-to-many class=".....QuestionAnswerDTO" />
</set>
.............
.............
例:
如果我们保存预订详情的收集
1. insert into reservation......... (reservation id = 1)
2. insert into reservation_detail....... (reservation detail id = 1)
3. insert into reservation_detail....... (reservation detail id = 2)
4. insert into question_answer..... (referece_type='RD' referece_id=0, question_id =1) - For Reservation Detail id = 1
5. insert into question_answer..... (referece_type='RD' referece_id=0, question_id =1) - For Reservation Detail id = 1
6. update reservation_detail set reservation_id = ? where reservation_detail_id = ? (reservation_id = 1, reservation_detail_id = 1)
7. update reservation_detail set reservation_id = ? where reservation_detail_id = ? (reservation_id = 1, reservation_detail_id = 2)
8. update question_answer set reference_id = ? where question_answer_id = ? (reference_id = 1 and question_answer_id =1)
9. update question_answer set reference_id = ? where question_answer_id = ? (reference_id = 2 and question_answer_id =2)
当系统执行point(5)脚本时 . 系统将通过约束违规异常 .
Is there any way that hibernate update reference_id in question_answer (table) immediately before creating next insert query.
Script 8 must run after 4th script
Script 9 must run after 5th script
2 回答
如果您已在子映射中正确映射父类,则Hiberate
cascade
选项会使用外键插入子对象 . 如果您没有在子映射中映射父类但是作为Integer
reference_id
,那么将使用单独的更新查询更新外键:如果您不能在子映射中指定父类对象,则可以使用变通方法 . 您可以将
reference_id
设置为null
允许(在表格上),您需要在子对象中设置referenceId=null;
. 然后Hibernate级联将插入子对象null
外键,然后调用更新查询来设置生成外键的referenceId
.注意:如果出现多次,则唯一列中的
null
值不会被视为重复值 .很可能你没有在QuestionAnswerDTO实体中定义一个返回主实体的引用,即ReservationDetails . 您应该在QuestionAnswerDTO中配置@MAnyToOne,其中@JoinColumn为“reference_id”,类似于
然后将reservationDetail属性设置为它所属的实际ReservationDetail对象 .
然后JPA将知道它需要使用对REservationDetails的引用来填充reference_id . 否则它将其视为任何其他字段