Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cascade 개념 미숙지로 인해 발생했던 에러 #102

Closed
myway00 opened this issue May 18, 2022 · 1 comment
Closed

Cascade 개념 미숙지로 인해 발생했던 에러 #102

myway00 opened this issue May 18, 2022 · 1 comment

Comments

@myway00
Copy link
Contributor

myway00 commented May 18, 2022

image

하나의 라우트 프로덕트는 여러 멤버를 가질 수 있고
한 멤버는 여러 라우트 프로덕트에 속할 수 있는 다대다 관계 맵핑을 위한 엔티티를 작성했습니다.
다대다 맵핑을 위해서 전 다대다 테이블을 만들어 위의 erd 테이블과 같이 구조를 짰습니다.

그래서 저는 라우트 프로덕트를 생성할 때, createrequest로 들어온 멤버들의 아이디를 검사하면서
멤버아이디 - 라우트프로덕트 아이디로 다대다테이블에 관계를 등록해주고 싶었습니다.

그러나 라우트 프로덕트를 생성을 해도 라우트프로덕트멤버 (다대다 테이블)에 전혀 관계가 저장이 안되는 것입니다.

에러 당시 RouteProduct.java 코드의 문제 부분입니다.

    @OneToMany(
            mappedBy = "routeProduct",
            orphanRemoval = true, 
            fetch = FetchType.LAZY
    )
    private List<RouteProductMember> members;

그리고 생성자입니다

    public RouteProduct(
            Integer sequence,

            Integer origin_seq,

            String name,
            RouteType type,
            String comments,
            boolean passed,
            boolean rejected,
            boolean show,
            boolean disabled,
            List<Member> member,
            RouteOrdering newRoute

    ) {
        this.sequence = sequence;

        this.origin_seq = origin_seq;


        this.route_name = name;

        this.type = type;
        this.comments = comments;
        this.passed = passed;
        this.rejected = rejected;
        this.route_show = show;
        this.disabled = disabled;
        this.members =
                member.stream().map(
                        r -> new RouteProductMember(
                                this, r)
                )
                .collect(toList());
        this.routeOrdering = newRoute;
    }
        this.members =
                member.stream().map(
                        r -> new RouteProductMember(
                                this, r)
                )
                .collect(toList());

위와 같이 new로만 해주어, 당연히 영속성 컨텍스트에 저장이 되지 않는 비영속 상태여서 저장이 되지 않는다는 문제를 파악했으나, 어떻게 이를 일일히 영속성 컨텍스트에 반영을 해주냐..? 라는 깊은 고민 속에서 몇 시간을 날렸습니다. ^^
(매번 저 친구를 빼서 하나하나 save() 해줘야 하나...분명 다른 방법이 있을 것인데 하며 말이죠~,,)

그러던 중 구글링을 통해 cascade 속성이 단순히 삭제 때만 적용되는 아이가 아닌, 부모 객체가 저장될 때 자식 객체도 저장해준다는 것을 알게 되었습니다. (저는 당시 cascade 개념을 전혀 알지 못해서 단순 삭제 때만 적용되는 속성인 줄로 알고 있었습니다. )

따라서 부모가 저장될 때 자식이 저장되는 ALL 옵션을 주어 라우트 프로덕트가 생성이 될 때 이의 자식인 라우트프로덕트멤버 에도 관계가 생성되게 해주었더니, 말끔히 정보가 잘 저장되는 것이었습니다.

    @OneToMany(
            mappedBy = "routeProduct",
            cascade = CascadeType.ALL,//이거 없애면 안돼 동윤아...
            orphanRemoval = true, 
            fetch = FetchType.LAZY
    )
    private List<RouteProductMember> members;

cascade 속성이 삭제할 때만 연관이 있겠지, 하고 전혀 이에 대한 학습을 하지 않고 코드를 짰다가 이 문제로 많은 시간을 허비하고 나서 스프링부트의 개념을 단단히 다져야 하는 것에 대한 중요성과 필요성을 다시 한번 느꼈었습니다.

다대다를 위한 테이블 생성 시 때 꼭 cascade 유무를 확인해봅시다!

@hehahihang
Copy link
Collaborator

특정 엔티티를 영속상태로 저장하고 연관 관계가 있는 엔티티까지 영속 상태로 저장하려고 할때도 cascade를 이용할 수 있군요!
처음 알게 됐네요 좋은 정보 공유 감사합니다ㅎㅎ

@myway00 myway00 closed this as completed May 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants