Как удалить запись при связи many to many с составным ключем?

Всем привет!

Похоже я намудрил в реализации, что не получается удалить запись.

Кейс словами: Есть сущности Листы, Операции, Коды Дефектов. Листы и операции образуют связную таблицу Завершенные операции с экстра колонкой сколько изделий пришло. Завершенные операции и Коды Дефектов образую связную таблицу Дефекты на завершенных операциях с колонкой количества бракованных изделий по кодам дефектов.

Выглядят сущности так: Листы:

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

    @NotBlank
    private String name;

    @NotNull
    @ManyToOne
    private Microchip microchip;

    @NotNull
    @ManyToOne
    private Execution execution;

    @NotBlank
    private String crystal;

    @NotBlank
    private String sewing;

    @NotBlank
    private String productBody;

    @OneToMany(mappedBy = "sheet", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
    private Set<SheetPassedOperation> sheetPassedOperations;

    @Lob
    private String comment = "";
}

Операции:

@Entity
public class Operation {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotBlank
    private String name;

    @OneToMany(mappedBy = "operation")
    private Set<SheetPassedOperation> sheetPassedOperations;
}

Коды дефектов:

@Entity
public class DefectCode {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(unique = true)
    @NotBlank
    private String code;
    @NotBlank
    private String name;
}

Завершенные операции:

@Entity
public class SheetPassedOperation {
    @EmbeddedId
    private SheetPassedOperationId id;
    @ManyToOne
    @MapsId("sheetId")
    private Sheet sheet;
    @ManyToOne
    @MapsId("operationId")
    private Operation operation;
    @NotNull
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private LocalDateTime startedAt;
    @NotNull
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private LocalDateTime finishedAt;
    @NotNull
    @Min(0)
    private Integer income;
    @OneToMany(mappedBy = "sheetPassedOperation", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<DefectPassedOperation> defects;
}

Дефекты на операциях:

@Entity
public class DefectPassedOperation {
    @EmbeddedId
    private DefectPassedOperationId id;
    @ManyToOne
    @MapsId("sheetId")
    private Sheet sheet;
    @ManyToOne
    @MapsId("operationId")
    private Operation operation;
    @ManyToOne
    @MapsId("defectCodeId")
    private DefectCode defectCode;
    @NotNull
    @Min(1)
    private Integer quantity;
    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "sheet_id", referencedColumnName = "sheet_id", insertable = false, updatable = false),
            @JoinColumn(name = "operation_id", referencedColumnName = "operation_id", insertable = false, updatable = false)
    })
    private SheetPassedOperation sheetPassedOperation;
}

У меня не получается удалить DefectPassedOperation в контроллере, пробовал делать его репозиторий и через него удалять. Есть репозиторий SheetPassedOperation, но удаление в коллекции дефекта и сохранение образца класса не дало удаление из базы дефекта. В логе хибернета нет вызова удаления.

Так же пробовал сделать сервис с использованием транзакции, но не помогло.

Похоже чего-то не знаю в тонкости работы хибернета. Прошу подсказки знатоков


Ответы (1 шт):

Автор решения: Evgeny Novoselov

Была проблема в связи из-за свойства

cascade = CascadeType.ALL

поменял на

cascade = CascadeType.REMOVE

и убрал у сущности листа.

orphanRemoval = true

Так же из-за исправлений поправил добавление и редактирование новых элементов

→ Ссылка