아래와 같이 두 클래스 Book
, BookStore
가 있다.
둘을 연관관계 매핑
을 했다고 생각했는데, 코드를 돌려보니 막상 DB에 정보가 반영되지 않는다
. 왜 일까?
// Book.java
@Entity
@Getter @Setter
public class Book {
@Id
@GeneratedValue
private Long id;
private String isbn;
private String title;
@ManyToOne
private BookStore bookStore;
}
// BookStore.java
@Entity
@Getter @Setter
public class BookStore {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany
private List<Book> books = new ArrayList<>();
public void add(Book book) {
this.books.add(book);
}
}
// contextLoad 코드
...
@Test
public void contextLoad() {
BookStore bookstore = new BookStore();
bookRepository.save(bookStore);
Book book = new Book();
bookStore.add(book);
bookRepository.save(book);
}
다행히 문제를 듣고 정답을 얘기할 수 있었다. 영상에서는 이것도 모르면 JPA 쓰지 말라고 하시던데..ㅎㅎ 다행이다.
우선 위 코드와 같이 작성을 하면 양방향 관계가 매핑된 것이 아니라 단방향 관계 2개
가 세팅된 것이다.
여기에 추가로 BookStore
클래스에
@OneToMany(mappedBy = "bookStore")
private List<Book> books = new ArrayList<>();
를 적어주면 양방향으로 매핑되고, 연관관계의 주인을 Book
으로 한다는 의미가 된다.
이 상태에서 실제로 add 메서드를 호출했을 때, 양방향 연관관계 매핑의 효과를 보기 위해서는 저렇게 BookStore
의 books에만 추가를 해주는 것이 아니라 Book
에도 반영을 해줘야 한다.
즉, 아래 코드와 같이 연관 관계의 주인쪽에 데이터를 갱신
해주고, 반대로 매핑되어 있는 객체에도 반영
시켜 주는 작업이 필요하다.
public void add(Book book) {
book.setBookStore(this);
this.books.add(book);
}
더욱 더 근본적인 질문을 나에게 던지며 공부하는 습관을 기르자
라는 생각이 들었다.
- 나는
스프링을 왜 쓰는가
?어떤 점이 좋아서
쓰는가?- 나는
JPA를 왜 쓰는가
?객체 지향적으로 DB를 다루면서 조심해야 하는 부분
(이 영상에서 다룬 부분과 같이)은 뭘까?
앞으로도 항상 신경쓰며 개발 공부를 해 나갈 것이다.
영상 출처: 백기선님, JPA, OneToMany 양방향 관계 "MappedBy" 해설
https://www.youtube.com/watch?v=hsSc5epPXDs