[JPA, 스프링부트] JPA의 연관관계 맵핑 (feat. Repeated column in mapping for entity 에러)

minji·2022년 4월 18일
2

기본적인 연관관계 맵핑

우리가 보통 JPA를 이용해 연관관계를 맵핑할 때는 @ManyToOne(다대일 관계인 경우)과 @JoinColumn 어노테이션을 사용한다.

예를 들어, User 테이블과 Product 테이블이 있다고 가정하자.
그리고 다른 제3의 테이블에서 두 테이블(User, Product) 모두와 다대일 관계를 맺는 경우 다음과 같이 작성할 수 있다.

@ManyToOne을 통해 해당 테이블과 다대일 관계임을,
@JoinColumn을 통해 해당 테이블에서 특정 테이블의 pk를 외래키로 가짐을 선언할 수 있다.

결과적으로 발생하는 DDL은 아래와 같다.

참조한 테이블의 컬럼으로 user_id와 product_id가 포함되었으며,
외래키로 두 필드가 설정되었음을 확인할 수 있다.

여기서 주의해야할 점은 @JoinColumnname 속성에 단순히 참조하는 키의 컬럼명을 써주는게 아니라는 사실이다


두개 이상의 컬럼이 한 테이블을 참조하는 경우

다음과 같은 경우를 보자.
한 테이블 내에서 User 테이블을 2개의 컬럼이, Product 테이블을 2개의 컬럼이 참조한다.
이 경우 위와 같이 @JoinColumn 어노테이션을 설정한 후 돌려보면 아래와 같은 오류가 발생한다.... Repeated column in mapping for entity 라는 부분을 통해 같은 컬럼을 두 번 맵핑했다는 의미임을 예측할 수 있다..


해결법

이를 해결하기 위해서는 @JoinColumn 어노테이션의 속성이 정확히 무엇을 의미하는지 알아야 한다.

- name : 맵핑할 외래키의 이름
- referencedColumnName : 외래키가 참조하는 대상 태이블의 pk 이름

즉, 위의 product_id와 user_id 와 같은 실제 pk명은 name 속성이 아니라 referencedColumnName 속성에 적어주어야 한다.

따라서, 다음과 같이 수정 후 서버를 다시 돌려보자.

# 생성된 create 문

 create table exchange (
 	exchange_id bigint not null auto_increment, 
 	acceptor_confirm_yn bit not null, 
 	exchange_complete_dt datetime(6), 
 	exchange_complete_yn bit not null, 
 	requester_confirm_yn bit not null, 

	# 아래 4줄 주목!!
 	acceptor_id bigint not null, 
 	acceptor_product_id bigint not null, 

 	requester_id bigint not null, 
 	requester_product_id bigint not null, 
    
 	primary key (exchange_id))

위와 같이 우리가 name 속성에 설정한 이름으로 컬럼명이 설정되어 DDL이 생성된 것을 확인할 수 있다.

profile
SW Engineer

0개의 댓글