Java Hibernate在设置父项后尝试保留子项两次
我有这样的Hibernate映射: 家长:Java Hibernate在设置父项后尝试保留子项两次,java,hibernate,jpa,spring-data-rest,Java,Hibernate,Jpa,Spring Data Rest,我有这样的Hibernate映射: 家长: @OneToMany(mappedBy = "parent") @Valid private Set<Assignment> assignments; @OneToMany(mappedBy = "parent", CascadeType = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}) private Set<Assignment> assignm
@OneToMany(mappedBy = "parent")
@Valid
private Set<Assignment> assignments;
@OneToMany(mappedBy = "parent", CascadeType = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private Set<Assignment> assignments;
我遇到了这样的情况:父对象已经被持久化到数据库中,我得到了新的任务列表。我做了这样的事情(使用Spring数据JPA):
我在基本实体中有@PrePersist注释的方法(由这两个实体扩展),通过验证检查在@PrePersist中初始化的createdDate是否为null。基本实体包含:
@NotNull
@Column(name = "created_date")
protected LocalDateTime createdDate;
@PrePersist
public void prePersist() {
setCreatedDate(LocalDateTime.now());
setModifiedDate(LocalDateTime.now());
validateEntity();
}
private void validateEntity() {
Set<ConstraintViolation<BaseEntity>> violations = Validation.buildDefaultValidatorFactory().getValidator().validate(this);
if(!violations.isEmpty()) {
throw new RuntimeException(new ValidationMessageBuilder().build(violations));
}
}
我已经调试过,在@PrePersist赋值方法中,实体Hibernate为另一个对象调用它,它是Assignment@17646,其中包含Parent@17608,父元素包含子元素的集合,该集合包含一个元素@17609
为什么hibernate试图持久化另一个对象?以下是我对您的问题的观察:
validateEntity()
,因为
子项分配的createDatenull
EntityListeners
设置createdDate
和
modifiedDate
并验证您的bean值。。。然而,似乎
(这是我的猜测)您的验证方法正在迭代
(和验证)在休眠之前很久就在子任务上
对它们执行@PrePersist
@OneToMany(mappedBy = "parent")
@Valid
private Set<Assignment> assignments;
@OneToMany(mappedBy = "parent", CascadeType = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private Set<Assignment> assignments;
基类:将prePersist
方法重命名为:
@PrePersist
@PreUpdate
public void prePersistOrUpdate() {
setCreatedDate(LocalDateTime.now());
setModifiedDate(LocalDateTime.now());
validateEntity();
}
createdDate
)并避免将要创建的横向子对象
稍后对EntityListener
方法进行了修改:
prePersistOrUpdate()
(注意,我删除了@有效的
注释
因为我不知道它是用来做什么的…可能是
您的验证框架)newassignments
)被持久化
因此:
parent.getAssignments().addAll(newAssignments)代码>
parent.getAssignments().forEach(assignment->assignment.setParent(parent))代码>
parentRepository.merge(parent);//这将级联并保持新的分配代码>
我认为您应该只将赋值添加到parent并持久化parent,而不需要将parent设置为assignments您会遇到什么样的异常。。。你能发布它吗?@Antoniossss,如果我不设置parent,hibernate不会自动执行此操作,并尝试使用parentId=null来持久化赋值,这是不正确的。如果我更改实体关系并在分配的父映射中添加nullable=“false”,则hibernate会尝试执行相同的操作(将父映射设置为分配),并出现相同的异常。@CarlitosWay编辑并添加了异常。您是对的-问题都在验证中。经过一些改动后,一切正常!
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
@PrePersist
@PreUpdate
public void prePersistOrUpdate() {
setCreatedDate(LocalDateTime.now());
setModifiedDate(LocalDateTime.now());
validateEntity();
}