#java #spring #spring-boot #hibernate #spring-data-jpa
#java #весна #весенняя загрузка #спящий режим #spring-data-jpa
Вопрос:
У меня проблема с вызовом deleteById
в @DataJpaTest. Перепробовал много решений из похожих вопросов, но ничего не помогло. Вот сущность:
Сущность:
@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
в@OneToMany
аннотацию вProject
сущности - Добавить
deleteById
с@Transactional
помощью inProjectRepository
- Добавить
@Transactional
в качестве аннотации теста
Ничего из вышеперечисленного не работает, дочерние элементы не могут быть удалены. В журналах загрузки Spring DELETE
запрос также отсутствует. Что не так с моим тестом?
Ответ №1:
Решение состояло в том, чтобы правильно установить двунаправленную связь между parent
и childs
:
public void setParent(Project parent){
this.parent = parent;
parent.getSubProjects().add(this);
}