Hibernate5插入一对一关联实体时如何手动调整顺序解决外键约束异常
Hibernate 5 手动调整实体插入顺序解决方案
有三种成熟的方案可以解决该问题,可根据业务改造成本灵活选择:
方案1:使用Hibernate专属@Table注解指定插入优先级
这是改造成本最低的方案,无需修改业务逻辑,仅需在实体类上加注解调整插入优先级即可:
在实体C的类上添加注解:
// 注意是org.hibernate.annotations.Table,不是javax.persistence.Table @Table(appliesTo = "C对应的数据库表名", sqlInsertPriority = 10)
在实体D的类上添加注解:
@Table(appliesTo = "D对应的数据库表名", sqlInsertPriority = 5)
注:
sqlInsertPriority的数值越大,插入优先级越高,Hibernate会按照优先级从高到低的顺序执行实体插入操作,优先级相同的实体仍按Hibernate默认规则排序。
方案2:显式配置实体间的依赖关联
无需修改数据库结构,仅需在D实体中添加单向关联声明,Hibernate会自动识别依赖关系,调整插入顺序:
// 在D实体类中新增该属性,不影响原有字段映射逻辑 @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "D表指向C表的外键字段名", insertable = false, updatable = false) private C c;
注:设置
insertable = false和updatable = false是为了避免该关联属性影响原有业务的增改操作,不会修改D实体原有的字段映射规则。
方案3:手动控制持久化操作顺序
如果以上两种注解方案不符合业务要求,可以调整持久化逻辑:
- 关闭A实体到C、D的级联保存配置
- 在业务代码中先单独持久化C实体,再持久化D实体,最后持久化A、B实体
该方案灵活度最高,但需要修改原有持久化逻辑,改造成本相对更高。
额外说明:Hibernate 5之后调整了实体插入的默认排序规则,从原有的按实体名排序改为按表名排序,无特殊需求优先选择方案1即可。
内容的提问来源于stack exchange,提问作者Gaurang Sheth
相关产品推荐
相关产品推荐

