Проверка deleteById на JpaRepository не работает

#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());
    }
 

Во время тестирования дочерние элементы не удаляются каскадным способом. Я пробовал следующие вещи:

  1. Добавить orphanRemoval = true в @OneToMany аннотацию в Project сущности
  2. Добавить deleteById с @Transactional помощью in ProjectRepository
  3. Добавить @Transactional в качестве аннотации теста

Ничего из вышеперечисленного не работает, дочерние элементы не могут быть удалены. В журналах загрузки Spring DELETE запрос также отсутствует. Что не так с моим тестом?

Ответ №1:

Решение состояло в том, чтобы правильно установить двунаправленную связь между parent и childs :

     public void setParent(Project parent){
        this.parent = parent;
        parent.getSubProjects().add(this);
    }