외래키의 주인은 음식 Entity이지만 실제 외래키는 고객 Entity가 가지고 있다.
1 : N에서 N 관계의 테이블이 외래 키를 가질 수 있기 때문에 외래 키는 N 관계인 users 테이블에 외래 키 컬럼을 만들어 추가하지만 외래 키의 주인인 음식 Entity를 통해 관리한다.
1 대 N 관계에서는 일반적으로 양방향 관계가 존재하지 않는다.
1 대 N 관계에서 양방향 관계를 맺으려면 음식 Entity를 외래 키의 주인으로 정해주기 위해 고객 Entity에서 mappedBy 옵션을 사용해야 하지만 @ManyToOne 애너테이션은 mappedBy 속성을 제공하지 않기 때문이다.
여기서 주의할 점은 Order를 중간 테이블로 생성하기 때문에 @JoinTable 어노테이션으로 추가를 한다.
다른 특징으로는 주문 테이블은 PK가 없고 FK만 존재한다.
음식 Entity가 ManyToMany에서 주인 엔티이이기 때문에 설정을 음식 Entity에서 진행한다.
외래키의 주인이 아닌 user 엔티티쪽에서 food 엔티티를 저장하려고 하면 user 테이블과 food 테이블에는 정상적으로 저장이 되지만, order테이블을 확인해보면 food_id와 user_id 값이 들어가지 않는다.
외래키의 주인이 아닌 user엔티티에서 food를 저장하기 위해서는 addFoodList()라는 매서드를 만들고 사용한한다.
이때 외래키(연관관계) 설정을 위해 Food에서 userList를 호출하고 user 객체 자신을 add한다.
해당 결과는 DB 저장에는 문제가 되지 않으나, User를 사용하여 food의 정보를 조회할 수 없다.
food 엔티티에 addUserList() 매서드를 생성하여 user 정보를 추가하고, 해당 매서드에 객체 활용을 위해 user 객체에 food 정보를 추가하는 코드를 추가한다. -> user.getFoodList().add(this);
foodRepostiroy에서 Id 1번 값인 "아보카도 피자"가 출력된다.
List userList = 아보카도 피자를 시킨 유저 리스트 이다.
따라서 orders 테이블에 food_id 1인 아보카도 피자 를 시킨 user_id 1 그리고 user_id 2에 해당되는 Robbie와 Robert가 출력된다.
userRepository에서 Id 1번 값인 "Robbie"가 출력된다.
ListfoodList = Robbie가 가진 foodList 이다.
따라서 food 테이블에 있는 id 1번값과 2번 값에 해당하는 내용이 출력된다.
출력
아보카도 피자
50000.0
고구마 피자
30000.0
중간 테이블 orders를 직접 생성하여 관리하면 변경이 발생할 경우 컨트롤하기가 쉬워 확장성에 좋다.
이전까지는 User 엔티티와 Food 엔티티만 있었고 자동 생성된 중간 테이블을 사용했으나, 이제 직접 Order라는 엔티티를 만들었기 때문에 새롭게 관계를 설정해야 한다.
Food 엔티티
User 엔티티
Order 엔티티
이제 Order 엔티티가 Food와 User엔티티와 @ManyToOne 관계에서 외래키의 주인이므로 @JoinColumn으로 각각 Food와 User 엔티티를 불러온다.
반대로 Food와 User 엔티티는 외래키의 주인이 아닌 쪽으로 @OneToMany 어노테이션과 mappedby로 Order엔티티를 설정한다.
결과적으로 Food와 User가 중간 테이블인 Order테이블을 통해 조회가 가능하다.Order엔티티는 테이블에 Food와 User 엔티티의 외래키를 가지고 있고, 반대로 Food와 User는 Order엔티티를 가지고 있으나 테이블에는 반영이 되지 않는다.
즐겁게 읽었습니다. 유용한 정보 감사합니다.