이전까지 질문 엔티티와 답변 엔티티를 작성했고, 그 과정에서 질문 엔티티와 답변 엔티티가 유기적 관계에 있음을 명시하는 작업이 필요하다는 것을 확인했다. 질문 엔티티를 다음과 같이 수정하자.

다음과 같이 question 속성에 @ManyToOne 애너테이션을 추가해준다. 

답변은 하나의 질문에 여러개가 달릴 수 있는 구조이다. 따라서 답변은 Many(많은 것)가 되고 질문은 One(하나)이 된다. 따라서 @ManyToOne은 N:1 관계라고 할 수 있다. 이렇게 @ManyToOne 애너테이션을 설정하면 Answer 엔티티의 question 속성과 Question 엔티티가 서로 연결된다. (실제 데이터베이스에서는 ForeignKey 관계가 생성된다.)

@ManyToOne은 부모 자식 관계를 갖는 구조에서 사용한다. 여기서 부모는 Question, 자식은 Answer라고 할 수 있다.

그렇다면 반대방향, 즉 Question 엔티티에서 Answer 엔티티를 참조할수는 없을까?

가능하다. 답변과 질문이 N:1의 관계라면 질문과 답변은 1:N의 관계라고 할 수 있다. 이런경우에는 @ManyToOne이 아닌 @OneToMany애너테이션을 사용한다. Question 하나에 Answer는 여러개이므로 Question 엔티티에 추가할 답변의 속성은 List 형태로 구성해야 한다.

 

이를 구현하기 위해 Question 엔티티를 다음과 같이 수정하자.

답변 엔티티에서 @ManyToOne 어노테이션을 추가했듯, 질문 엔티티는 그와 반대로 @OneToMany 어노테이션만 추가하면 될 줄알았는데, 답변 엔티티와 달리 질문 엔티티의 수정 사항이 조금 더 복잡해졌다. 왜 그럴까?

 

우선, Answer 엔티티 객체로 구성된 answerList를 속성으로 추가하고 @OneToMany 어노테이션을 설정했다. 질문 객체(예:question)에서 답변을 참조하려면 question.getAnswerList()를 호출하기 위해서이다.

@OneToMany 어노테이션에 사용된 mappedBy는 참조 엔티티의 속성명을 의미한다. 즉, Answer 엔티티에서 Question 엔티티를 참조한 속성명 question을 mappedBy에 전달해야 한다.

CascadeType.REMOVE

질문 하나에는 여러개의 답변이 작성될 수 있다. 이때 질문을 삭제하면 그에 달린 답변들도 모두 함께 삭제하기 위해서 @OneToMany의 속성으로 cascade = CascadeType.REMOVE를 사용했다. 따라서 수정이 조금 복잡하게 이루어졌다.

 

이제 H2 콘솔에 다시 접속해보자.

ANSWER과 QUESTION 테이블이 생성되었다!

마지막으로 엔티티에 대해서 간략하게 정리하고 가자.

질문:답변 관계는 1:N이어야 하고, 답변:질문 관계는 N:1이어야 바람직하다.

 

 

++참고++

Question 엔티티와 Answer 엔티티 사이에 'ManyToOne' 관계를 설정할 때, 그러나 @ManyToOne 어노테이션이 id 필드 위에 위치해 있다면 제대로 된 관계 설정이 이루어지지 않는다!!

@ManyToOne 어노테이션은 Question 엔티티를 참조하는 필드인 question 필드 위에 위치해야 한다. 위 코드와 같이.

'백엔드 > Springboot' 카테고리의 다른 글

리포지터리(Repository) -2-  (0) 2023.09.18
리포지터리(Repository) -1-  (0) 2023.09.18
엔티티(Entity) -1-  (0) 2023.09.17
JPA 환경설정  (0) 2023.09.17
JPA  (1) 2023.09.17

+ Recent posts