我在@DataJpaTest中调用deleteById
时遇到问题。从类似的问题中尝试了许多解决方案,但都无济于事。这是实体:
实体:
@Setter
@Getter
@NoArgsConstructor
@Entity
@DynamicUpdate
@Table(name = "project")
public class Project{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column
private String description;
@Column
@CreationTimestamp
private LocalDateTime created;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Project parent;
@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE, orphanRemoval = true)
private Set<Project> subProjects = new HashSet<>();
}
JpaRepository
@Repository
public interface ProjectRepository extends JpaRepository<Project, Long>{
}
测试
@Test
void givenParentAndChilds_whenDeleteParent_thenDeleteChilds() {
// Given
Project parent = Project.builder().name("parent").build();
parent = projectRepository.save(parent);
Project child1 = Project.builder().name("child1").build();
child1.setParent(parent);
child1 = projectRepository.save(child1);
Project child2 = Project.builder().name("child2").build();
child2.setParent(parent);
child2 = projectRepository.save(child2);
Project child3 = Project.builder().name("child3").build();
child3.setParent(parent);
child3 = projectRepository.save(child3);
assertTrue(projectRepository.findById(parent.getId()).isPresent());
assertTrue(projectRepository.findById(child1.getId()).isPresent());
assertTrue(projectRepository.findById(child2.getId()).isPresent());
assertTrue(projectRepository.findById(child3.getId()).isPresent());
// When
projectRepository.deleteById(parent.getId());
// Then
assertFalse(projectRepository.findById(parent.getId()).isPresent());
assertFalse(projectRepository.findById(child1.getId()).isPresent()); // <-- these assertions fails
assertFalse(projectRepository.findById(child2.getId()).isPresent());
assertFalse(projectRepository.findById(child3.getId()).isPresent());
}
在测试期间,不会通过级联删除子项。我尝试了以下方法:
- 将
orphanRemoval = true
添加到Project
实体中的@OneToMany
注释 - 在
ProjectRepository
中添加deleteById
和@Transactional
- 添加
@Transactional
作为测试注释
以上都不起作用,不能删除子项。在Spring Boot日志中,也缺少DELETE
查询。我的测试出了什么问题?
解决方案是正确设置parent
和childs
:之间的双向链接
public void setParent(Project parent){
this.parent = parent;
parent.getSubProjects().add(this);
}