JPA를 사용해 값을 저장할 때, @ManyToOne 으로 매핑된 클래스 필드(외래키 참조)의 값을 key 값으로 부여하는 방법

조회수 2260회

Entity내부에 연관관계를 설정하기 위해 @ManyToOne애노테이션을 이용해 매핑하였습니다. 예를들면 다음과 같습니다.

예제 엔티티

@Entity
public class Book {
    @Id
    @GeneratedValue
    private long id;

    @Column
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    private Publisher publisher

    // getter & setter
}

@Entity
public class Publisher {
    @Id
    @GeneratedValue
    private long id;

    @Column
    private String name;

    // getter & setter
}

각 생성되는 테이블명은 book, publisher 이고 PK(=id)가 1publisher의 정보가 저장되어 있다고 간주했을 때 값을 저장하기 위해 다음처럼 JSON객체를 전달하려 했습니다.

새로운 Book 을 생성

Controller:

@PutMapping(value = "/books")
public ResponseEntity createBook(@RequestBody Book book) {
    bookRepository.save(book);

    // 생략
}

요청 본문:

{
  "name" : "jpa in action",
  "publisher" : "1"
}

대충 내용을 추려서 작성하였습니다. 문제는 위처럼 요청 본문을 전달하게 되면, Publisher엔티티가 단일 숫자타입 매개변수를 갖는 생성자가 없어서 요청을 처리할 수 없다는 에러가 발생하게 됩니다.

궁금한 것

기본적으로 JPA에서 findOne등의 미리 구현된 기능을 이용해 PK(=id)를 매개변수로 해당 값을 조회하는 것 처럼, 요청본문에서 PK(=id)를 전달해서 자동으로 참조하는 값을 조회하고 저장할 수 있는 방법이 없을까요? 아니면 위와같은 로직에서는 별도의 PK(=id)값을 필드로 받아서 직접 Publisher를 조회하고 Book객체에 book.setPublisher(publisher)와 같이 수동으로 작업을 해줘야 하는 건가요?

추가로

실제 데이터베이스 테이블에는 Foreign Key로 값이 들어있는데, 위의 상황에서면 publisher_id가 되겠죠. 그래서 요청본문에 "publisher_id" : 1, 을 추가해도 실제 테이블의 publisher_id컬럼에는 값이 저장되지 않았습니다. 어떻게 해야 할까요?

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 저장하실때 몇가지 전략을 가지고 하셔야 합니다. 업무 성격에 따라. cascade 정책을 어떤 정책을 가져가실지 먼저 정하시구요.

    JPA에서 기본적으로 저장하기전에 findOne으로 검색해서 해당 내용을 업데이트 할지 신규저장할지 판단합니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)