【发布时间】:2021-01-09 20:55:57
【问题描述】:
我知道它可能会重复。但我被困住了。
当我尝试更新以下实体时。我得到以下异常
拥有的实体实例不再引用具有 cascade="all-delete-orphan" 的集合:com.sip.nglis.partneruser.entities.UserEntity.userPostNominals;
以下是关于实体和我的逻辑的信息
@Entity
@Table(name = "user", schema = "user_management")
public class UserEntity extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Integer userId;
@Column(name = "display_code")
private String displayCode;
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinColumn(name = "reporting_to", referencedColumnName = "user_id")
private UserEntity reportingTo;
@OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true)
private Set<UserRoleEntity> userRoles;
@OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true)
private Set<UserPostNominalEntity> userPostNominals;
getters... setters...
}
用户服务:
@Transactional
public void updateUser(UserWithDependenciesDto user){
modelMapper.addConverter(CommonUtil.BOOLEAN_SHORT_CONVERTER);
UserEntity updatedUser = modelMapper.map(user.getUser(), UserEntity.class);
UserEntity userEntity = userDao.findOne(user.getUser().getUserId());
// Skipping the fields which will be updated accordingly
modelMapper.typeMap(UserEntity.class, UserEntity.class).addMappings(mapping -> {
mapping.skip(UserEntity::setUserPostNominals);
mapping.skip(UserEntity::setUserRoles);
});
// replace the entity with updated data
modelMapper.map(updatedUser, userEntity);
//Remove Post Nominal
userEntity.getUserPostNominals().stream().filter(postNominal -> !userDto.getPostNominal().contains(postNominal.getUserPostNominalPK().getPostNominalId())).collect(Collectors.toSet()).forEach(userEntity.getUserPostNominals()::remove);
// Add Post Nominal
Set<UserPostNominalEntity> postNominalEntities = new HashSet<>();
for (Integer postNominal : user.getUser().getPostNominal()) {
if (!userEntity.getUserPostNominals().stream().anyMatch(postNominalEntity -> postNominalEntity.getUserPostNominalPK().getPostNominalId() == postNominal)) {
UserPostNominalEntity userPostNominalEntity = new UserPostNominalEntity();
userPostNominalEntity.setUser(userEntity);
userPostNominalEntity.getUserPostNominalPK().setPostNominalId(postNominal);
userPostNominalEntity.getUserPostNominalPK().setUserId(userEntity.getUserId());
postNominalEntities.add(userPostNominalEntity);
}
}
postNominalEntities.addAll(userEntity.getUserPostNominals());
if(!postNominalEntities.isEmpty()){
userEntity.getUserPostNominals().clear();
userEntity.getUserPostNominals().addAll(postNominalEntities);
}
// Remove Roles
List<Integer> roleIds = userDto.getRoles().stream().map(userRole -> userRole.getRoleUId()).collect(Collectors.toList());
userEntity.getUserRoles().stream().filter(userRole -> !roleIds.contains(userRole.getRole().getRoleUId())).collect(Collectors.toSet()).forEach(userEntity.getUserRoles()::remove);
//Add Roles
Set<UserRoleEntity> userRoles = new HashSet<>();
for (RoleDto role : user.getUser().getRoles()) {
if (!userEntity.getUserRoles().stream().anyMatch(userRoleEntity -> userRoleEntity.getRole().getRoleUId() == role.getRoleUId())) {
UserRoleEntity userRoleEntity = new UserRoleEntity();
modelMapper.getConfiguration().setSkipNullEnabled(true);
RoleEntity roleEntity = modelMapper.map(role, RoleEntity.class);
userRoleEntity.setRole(roleEntity);
userRoleEntity.setUser(userEntity);
userRoleEntity.setAddedBy(user.getCreatedBy());
userRoleEntity.setAddedTimestamp(Timestamp.from(Instant.now()));
userRoleEntity.getId().setRoleId(roleEntity.getRoleUId());
userRoleEntity.getId().setUserId(userEntity.getUserId());
userRoles.add(userRoleEntity);
}
}
userRoles.addAll(userEntity.getUserRoles());
if(!userRoles.isEmpty()){
userEntity.getUserRoles().clear();
userEntity.getUserRoles().addAll(userRoles);
}
userDao.update(userEntity);
}
用户存储库:
public UserEntity update(UserEntity user) {
return entityManager.merge(user);
}
上述异常仅在我尝试更新UserEntity中的reportingTo时发生,如果我在映射过程中尝试跳过它并且不更新reportingTo 然后 上述异常消失。
如果我在服务 updateUser 方法中这样做
modelMapper.typeMap(UserEntity.class,
UserEntity.class).addMappings(mapping -> {
mapping.skip(UserEntity::setUserPostNominals);
mapping.skip(UserEntity::setReportingTo);
mapping.skip(UserEntity::setUserRoles);
});
由于上述代码完全删除了针对用户更新它的 reportingTo,因此上述异常消失了。
reportingTo 是一个分离的对象,因此该对象具有唯一的 ID,其余字段为空。
【问题讨论】:
-
当一个人希望父母的变化传播给它的孩子而不是相反时,使用级联 ALL...乍一看,我猜@ManyToOne 关系中的
cascade all首先不应该在那里......见stackoverflow.com/questions/13027214/… -
@francisconeto 让我检查级联合并。如果有效,将返回
-
@francisconeto 谢谢。那是罪魁祸首。我完全从reportingTo 中删除了级联。我觉得有点愚蠢,为什么我还要这样做。尽管在所有其他地方,我没有在具有多对一关系的子实体上放置级联。请移动您的评论以回答,以便我标记它。
-
很高兴能帮上忙
标签: java hibernate spring-data-jpa