NextStep의 ATDD 과정의 미션을 진행하면서 나 자신에게 적잖이 충격이었다.
그렇게 영한님의 JPA 강의를 통해 학습하고, 영한님의 JPA 책을 읽고, 토이 프로젝트에도 적용해보았는데도 이걸 지금 깨달았다는 게 약간 충격이다.
이번 글은 정말 초보적인 이슈이지만 창피를 무릅쓰고 박제(?)함으로써, 좀 더 개념 공부할 때 제대로 집중하자는 다짐을 해본다.
@Entity
public class Station {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "station_id")
private Long id;
@Column(length = 20, nullable = false)
private String name;
}
@Entity
public class Line {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 20, nullable = false)
private String name;
@OneToOne(fetch = LAZY)
@JoinColumn(name = "station_id") // ←← 문제의 원인
private Station upStation; // 연관 관계 매핑
@OneToOne(fetch = LAZY)
@JoinColumn(name = "station_id") // ←← 문제의 원인
private Station downStation; // 연관 관계 매핑
@Column(nullable = false)
private Long distance;
}
@JoinColumn
개념나는 지금까지 @JoinColumn
속성 중 name
에는 대상 엔티티를 매핑하기 위해 "Join"할 컬럼명을 지정해주어야 되는 걸로 알고 있었다.
예를 들어 Station
Entity 객체의 pk 값이 station_id
일 때 매핑하려는 외부 Entity 객체(Line
)에서 @OneToOne
으로 매핑할 때 JoinColumn(name=”조인할 컬럼명”)
으로 설정해주어야 되는줄 알고 있었다.
근데 Document를 보니 @JoinColumn
의 name
속성 값은 대상 엔티티와 “매핑할 외래 키(자기 필드명)” 이름을 지정해주는 값이고, “조인할 컬럼명(외래 키가 참조하는 대상 테이블의 컬럼명)”을 지정해주는 속성 값은 referencedColumnName
이었던 것이다
또한 우리가 평소에 referencedColumnName
을 따로 설정해주지 않아도 알아서 매핑이 됐었던 이유는, referencedColumnName
의 default 값이 참조하는 대상 테이블의 기본 키(pk)의 변수명으로 알아서 조인하도록 동작하기 때문이다.
결국 MappingException이 발생한 이유는 2개의 필드(컬럼)에서 같은 컬럼명으로 매핑하려다가 실패한 것이었다.
@OneToOne(fetch = LAZY)
@JoinColumn(name = "station_id") // ←← 문제의 원인
private Station upStation; // 연관 관계 매핑
@OneToOne(fetch = LAZY)
@JoinColumn(name = "station_id") // ←← 문제의 원인
private Station downStation; // 연관 관계 매핑
위에 중복으로 선언된 컬럼명을 각기 다른 컬럼으로 변경하였다.
사소한거라도 기초를 좀 더 단단히 다져야겠다는 생각을 했다..!
안녕하세요! 글 잘 보았습니다!
다름이 아니라 문서에서 어떻게 한글로 설명이 나오게끔 하는지 궁금합니다!