💻 현생/📋 스터디

[Spring] 양방향 매핑은 쓰기 싫은데, cascade 옵션은 주고 싶다면?(MySQL)

영이오 2021. 8. 2. 20:07

일단 문제의 엔티티를 보자

 

Book

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Book {

    @Id
    @Column(name = "book_sn")
    @GeneratedValue
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_sn")
    @NotNull
    private User user;

    @NotNull
    private String title;

    @Column(length = 300)
    private String thumbnail;

    private String author;

    private String publisher;

    @Lob
    private String description;

    @NotNull
    private String isbn;

    private Integer totPage;

    @Column(length = 300)
    @NotNull
    private String url;

    @Enumerated(EnumType.STRING)
    private BookStatus bookStatus;

    private LocalDate startDate;

    private LocalDate endDate;

    private Integer score;

    private Integer readPage;

    @Lob
    private String expectation;
}

 

Memo

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class Memo {

    @Id
    @Column(name = "memo_sn")
    @GeneratedValue
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "book_sn")
    @OnDelete(action = OnDeleteAction.CASCADE)
    @NotNull
    private Book book;

    @Lob
    @NotNull
    private String content;

    @NotNull
    private LocalDateTime saved;
}

 

대충 설명하면 책에는 n개의 메모를 남길 수 있다.

근데 책->메모로 탐색할 일이 많지 않아서 단방향 매핑을 해뒀다.

 

그리고 문제가 발생했다.

cascade option을 주지 않으면 자식이 있는 부모 객체를 삭제할 수 없다. DB 수업 들으면 배운다.

 

물론 JPA에서 cascade option을 줄 수 있다.

 

    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL) //constraint 용
    private List<Memo> memos = new ArrayList<>();

이런식으로 하면 된다.

 

근데 이건 보통 양방향 매핑에서 하는건데 고작 cascade를 위해 쓰지 않을 뭐 이런걸 남겨주는게 영 그랬다.

분명히 방법이 있을텐데...

 

https://stackoverflow.com/questions/7197181/jpa-unidirectional-many-to-one-and-cascading-delete

 

JPA: unidirectional many-to-one and cascading delete

Say I have a unidirectional @ManyToOne relationship like the following: @Entity public class Parent implements Serializable { @Id @GeneratedValue private long id; } @Entity public cl...

stackoverflow.com

있다!

 

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "book_sn")
    @OnDelete(action = OnDeleteAction.CASCADE)
    @NotNull
    private Book book;

똑같이 해주고 yml도 update로 바꿔서 실행했다.

 

근데 또 안된다 왜??

 

이게 뭔소리일까 db 생성에만 영향을 주고 update에는 안먹는다는걸까? 아니 근데 굳이 그럴 필요가 있나?

 

https://stackoverflow.com/questions/41465852/ondelete-hibernate-annotation-does-not-generate-on-delete-cascade-for-mysql

 

@OnDelete Hibernate annotation does not generate ON DELETE CASCADE for MySql

I have two entities parent and child with a unidirectional relationship class Parent { @Id @GeneratedValue(strategy= GenerationType.AUTO) private Long id; } and class Child { @Id...

stackoverflow.com

https://stackoverflow.com/questions/50353930/hibernate-ondelete-cascademanytoone-not-working-for-mysql

 

Hibernate OnDelete Cascade(@ManyToOne) not working for MySql

I have ManyToOne mapping and I wish to delete all the child elements upon deletion of Parent.Unfortunately @OnDelete(action = OnDeleteAction.CASCADE) is creating a foreign key constraint (on delete =

stackoverflow.com

어째 안된다는 글마다 db가 mySQL인지? 마침 나도 그걸 사용하는데...

 

흠...잘 모르겠다만 만약 이게 mySQL만의 문제라면

그냥 워크벤치에서 해결하면 그만 아닌가

 

오 잘된다.

 

만약 ddl-auto가 create일 때만 작동하고 update일 때는 안된다는 가설(이게 말이 되나?)이 사실이라면 안되는게 말이 된다. 그치만 될지 안될지도 모르는데 지금 있는 테스트 유저 데이터를 다 날리면서 create를 해볼만큼 성실한 사람이 아니라...

 

아무튼 이 부분은 나중에 실험을 해야겠다.

 

-> 2021.08.11 실험

create로 하고 실행하면 cascade가 먹는다!