Hibernate一对多关联时重复插入父实体Upload问题排查
嘿,我来帮你拆解下这个问题——创建带空Filter列表的Upload时生成两条属性一致但主键不同的记录,大概率和Session管理、关联映射配置或者代码逻辑的小疏漏有关,咱们一条条捋:
Session操作重复或对象状态管理失误
你提到用了session.get(),但先检查下代码里是不是不小心调用了多次session.save()/session.persist()。比如,是不是在同一个请求流程里,对同一个(或者属性完全相同的两个)Upload对象执行了两次持久化操作?
另外要注意:如果是两个不同的实例(哪怕属性完全一样),Hibernate会把它们当成两个全新的实体,生成两条不同主键的记录。比如你在DTO转实体时不小心创建了两个Upload对象,然后都存了进去,就会出现这种情况。一对多关联的映射配置踩坑
因为Upload和Filter是一对多关系,得仔细核对映射配置:- 检查Filter类里的
@ManyToOne关联是不是加了不必要的级联?比如cascade = CascadeType.PERSIST或者ALL,虽然你说Filter列表是空的,但如果代码里不小心生成了空的Filter实例并关联到Upload上,可能会触发异常的级联逻辑。 - 再看Upload的
@OneToMany配置,mappedBy(或XML里的inverse属性)是不是设置错了?如果Upload作为主控方的配置出现偏差,可能会导致Hibernate对对象状态的判断出错,触发重复保存。
- 检查Filter类里的
事务边界或传播行为的问题
要是REST接口的事务配置有问题,也可能出现这种情况:比如方法里开启了多个事务,或者用了REQUIRES_NEW这种传播行为,导致同一个对象在不同事务里被重复持久化。举个例子,如果你在一个事务里保存了Upload,然后又调用了另一个带REQUIRES_NEW事务的方法,再次保存同一个对象,就会生成两条记录。session.get()的逻辑判断失误
你用了session.get()来获取对象,会不会是在创建新Upload时,判断逻辑出了问题?比如你以为能查到某个Upload,但实际上因为ID不正确或者Session缓存的问题,每次都查不到,于是重复创建新的Upload并保存?
排查建议
- 先给持久化代码加日志,记录每次调用
session.save()时的对象hashCode和时间,确认是同一个对象被多次保存,还是不同对象被保存。 - 核对映射注解/XML配置,重点检查一对多的级联规则、
mappedBy/inverse的设置,确保关联关系正确。 - 梳理整个REST接口的处理流程,看看有没有拦截器、切面或者方法内部的条件分支,不小心触发了多次保存操作。
- 检查事务配置,确认事务边界和传播行为是否合理,有没有在同一个请求中多次提交事务。
内容的提问来源于stack exchange,提问作者user2312386

