Hibernate报错:带有cascade='all-delete-orphan'的集合不再被所属实体实例引用的问题求助
Hibernate报错:带有cascade='all-delete-orphan'的集合不再被所属实体实例引用的问题求助
各位好,我现在遇到一个头疼的Hibernate问题,实在搞不定了,来请教大家!
我有个ProcedureStep实体,其中的subSteps集合配置了CascadeType.ALL和orphanRemoval = true。现在当我尝试保存从前端传来的实体时,总是抛出这个错误:
A collection with cascade='all-delete-orphan' was no longer referenced by the owning entity instance: br.com.unika.pathdetail.entity.ProcedureStep.subSteps.
奇怪的是,我在Java代码里并没有修改或者重新赋值这个subSteps集合啊——我只是把前端传过来的内容直接转成实体就保存了。但Hibernate好像还是认为原来的集合引用被替换或者丢失了。
我已经试过各种能想到的办法了,比如检查集合的初始化逻辑、确认没有在代码里重新new ArrayList()赋值,但都没用。下面是我的相关代码:
1. ProcedureStep实体类
@Entity @Table(name = "procedure_step", indexes = { @Index(name = "idx_pstep_code", columnList = "code, procedure_id"), }) @Data public class ProcedureStep extends AbstractEntity<ProcedureStep, ProcedureStepDTO> { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @AuditableObject(mapBy = "id") @ManyToOne(fetch = FetchType.EAGER, optional = false) @JoinColumn(name = "account_id", updatable = false) private Account account; @AuditableObject(mapBy = "name") @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "procedure_id", updatable = false) private Procedure procedure; @AuditableObject(mapBy = "name") @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "parent_step_id") private ProcedureStep parentStep; // ex: 1.1.1 @Auditable @Column(nullable = false, length = 20) private String code; @Auditable @Column(name = "name", nullable = false) private String name; @Temporal(TemporalType.TIMESTAMP) @Column(nullable = false, name = "created_date", updatable=false) private Date createdDate = new Date(); @OneToMany(mappedBy = "step", cascade = CascadeType.ALL, orphanRemoval = true) private List<StepParameter> parameters = new ArrayList<>(); @OneToMany(mappedBy = "parentStep", cascade = CascadeType.ALL, orphanRemoval = true) private List<ProcedureStep> subSteps = new ArrayList<>(); }
2. 批量保存方法saveMany
@Transactional(rollbackFor = Exception.class) public List<ProcedureStepDTO> saveMany(List<ProcedureStepDTO> dtoList) throws BusinessRuleException { Set<String> newObjs = new HashSet<>(); // 把所有DTO转成实体 List<ProcedureStep> toSave = dtoList.stream().map(ProcedureStepDTO::toEntity).toList(); for (ProcedureStep entity : toSave) { validateUpdatePermission(entity); if(entity.getId() == null) { newObjs.add(entity.getUuidCheck()); beforePersist(entity); } else { beforeSave(entity); } commonValidations(entity); } List<ProcedureStep> saved = repository.saveAll(toSave); for (ProcedureStep s : saved) { if(newObjs.contains(s.getUuidCheck())) { this.afterPersist(s); } else { this.afterSave(s); } } return saved.stream().map(ProcedureStep::toDTO).toList(); }
3. DTO转实体的toEntity方法
@Override public ProcedureStep toEntity() { ProcedureStep entity = new ProcedureStep(); this.mapCommonFields(entity); entity.setCode(this.getCode()); entity.setName(this.getName()); entity.setCreatedDate(this.getCreatedDate()); if (this.account != null) { entity.setAccount(this.account.toEntity()); } if (this.procedure != null) { entity.setProcedure(this.procedure.toEntity()); } // 更新parameters集合 if (entity.getParameters() == null) { entity.setParameters(new ArrayList<>()); } entity.getParameters().clear(); if (this.getParameters() != null && !this.getParameters().isEmpty()) { this.getParameters().forEach(parameter -> entity.getParameters().add(parameter.toEntity())); } // 更新subSteps集合 if (entity.getSubSteps() == null) { entity.setSubSteps(new ArrayList<>()); } entity.getSubSteps().clear(); if (this.getSubSteps() != null && !this.getSubSteps().isEmpty()) { this.getSubSteps().forEach(subStepDTO -> entity.getSubSteps().add(subStepDTO.toEntity())); } return entity; }
我特意在toEntity里用了先清空集合、再逐个添加元素的方式,完全没有重新赋值集合引用(比如entity.setSubSteps(new ArrayList<>())这种操作只有在集合为null的时候才会做,但实体里已经初始化了集合啊)。
实在搞不懂为什么Hibernate还是会报这个错,有没有大佬遇到过类似的情况?求指点一下可能的原因和解决办法,万分感谢!
相关产品推荐
相关产品推荐

