У меня есть несколько связных сущностей:
@NoArgsConstructor
@Getter @Setter
@Entity
public class Organization extends AbstractIdentifiable {
@Column(nullable = false, unique = true)
@NotBlank
private String title;
@ManyToOne(optional = false)
@JoinColumn(nullable = false)
private Member registrationMember;
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Calendar registrationDateTime;
@OneToOne(mappedBy = "organization", cascade = CascadeType.ALL)
private Site site;
@OneToOne(mappedBy = "organization", cascade = CascadeType.ALL)
private Advertiser advertiser;
}
@NoArgsConstructor
@Getter @Setter
@Entity
public class Advertiser extends AbstractIdentifiable {
@OneToOne(optional = false)
@JoinColumn(nullable = false)
private Organization organization;
@ManyToMany(mappedBy = "advertisers")
private Set<Member> members = new HashSet<>();
@OneToMany(mappedBy = "advertiser", cascade = CascadeType.ALL)
private Set<PaidVideo> paidVideos = new HashSet<>();
}
@NoArgsConstructor
@Getter @Setter
@Entity
public class PaidVideo extends AbstractIdentifiable {
@OneToOne(optional = false)
@JoinColumn(nullable = false)
private Video video;
@ManyToOne(optional = false)
@JoinColumn(nullable = false)
private Advertiser advertiser;
@OneToMany(mappedBy = "paidVideo", cascade = CascadeType.ALL)
private Set<Booking> bookings = new HashSet<>();
}
Перечислил только те, что имеют непосредственное отношение к вопросу, от общей сущности (вверху), к зависимым (внизу).
Пытаюсь удалить сущность Organization. Ожидаю, что по каскадной операции (cascade = CascadeType.ALL) будут удалены все связные сущности: Advertiser, PaidVideo и так далее:
@Log4j2
@Controller
@RequestMapping("/api/organizations")
public class OrganizationController {
@Autowired
private OrganizationRepository organizationRepository;
@PreAuthorize("hasRole('ADMIN')")
@Transactional
@RequestMapping(value = "/{id}/delete", method = RequestMethod.POST)
public ResponseEntity delete(@PathVariable("id") Long id) {
organizationRepository.deleteById(id);
return ResponseEntity.ok().build();
}
}
Однако этого не происходит. Hibernate выкачивает все связные сущности, а после пытается первой и единственной удалить сущность Advertiser, закономерно получая ошибку ограничения целостности: https://pastebin.com/Z0M9BdM7
Чем может быть вызвано такое поведение? Разве hibernate не должен был построить дерево зависимостей сущностей и удалять их начиная с листьев? Почему при удалении Organization происходит только попытка удаления Advertiser, игнорируя зависимые сущности Advertiser? При чем это единственная попытка удаления чего либо, она происходит при вызове метода organizationRepository.deleteById(id); и после происходит выход из транзакционного метода, и коммит транзакции. В общем, колдунство какое-то.
Граф связей таблиц в БД: https://i.imgur.com/lPixAnd.png