JPA 양방향 관계 "MappedBy"

최민수·2023년 3월 28일
0

[개발] Java Spring

목록 보기
11/18


질문

아래와 같이 두 클래스 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

profile
CS, 개발 공부기록 🌱

0개의 댓글