Search code examples
javajpaspring-data-jpaone-to-many

OneToMany deleteById method in JPA repository is not working


I have entities and store them in h2 database. All unnecessary fields are omited.

@Data
@Table
@Entity
public class Section {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToMany(mappedBy = "section", cascade = CascadeType.ALL, orphanRemoval = true)
  private Set<Subsection> subsections = new HashSet<>();
}

@Repository
public interface SectionRepository extends JpaRepository<Section, Long> {}

@Data
@Table
@Entity
public class Subsection {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @ManyToOne
  @JoinColumn(name = "SECTION_ID")
  private Section section;
}

@Repository
public interface SubsectionRepository extends JpaRepository<Subsection, Long> {}

Firstly I save one Section and one Subsection. Result in h2-console:
enter image description here
Then I want to delete Subsection from Section. Method example:

public void deleteById(Long id) {
  subsectionRepository.deleteById(id);
}

As a result nothing is deleted. I tried to add orphanRemoval = true but no effect. I also tried to remove parent from child and save Subsection again without parent and then call deleteById(id) method and as a result row was not deleted but value in SECTION_ID was null. Also tried following settings in Subsection.

  @ManyToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "SECTION_ID")
  private Section section;

But as it was expected child was deleted with parent. Do I use some annotations incorrectly or I forgot to add something? What is the reason that child can't be deleted?


Solution

  • Then I want to delete Subsection from Section. Method example:

    public void deleteById(Long id) {
    subsectionRepository.deleteById(id); }

    What you want to do, would not be done the way you try it. As you have configured it it would be

    Subsenction subsenction1 = subsectionRepository.findById(id); 
    section.getSubSenctions().remove(subsenction1);
    

    Then it will be dereferenced from Table Senction. After that because of orphan removal it would be also removed from table Subsenction

    Another pitfall that is very common is hashCode() and equals() methods that are not based on the ID field on JPA objects or are the default ones which from JVM are not based on ID field anyways.