결론: @JoinColumn(referencedColumnName = [참조하는 필드 이름])
오류 상황
공부 겸 진행중인 스프링 부트 프로젝트에서 생긴 문제이다. Solved라는 table에서 School의 필드를 참조하는 FK를 가져야 하는 상황이다. 각 Entity 코드는 다음과 같다.
- School
@Entity
public class School implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="school_id", nullable = false, unique = true)
private Long schoolId; // 학교 번호
@OneToMany(mappedBy = "school")
private Set<Solved> solvedSet = new HashSet<>();
...
}
- Solved
@Entity
public class Solved {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "school_id")
private School school;
...
}
처음에 생각으로는 @JoinColumn(name = "school_id")라고 입력했으니까 당연히 Hibernate가 school_id를 참조하지 않을까 생각했다. 책과 인터넷에 나오는 예제도 다 이런 식으로만 작성되어 있었고...
그런데 아니었다. Hibernate에서는 자꾸 school_id column이 아닌 id column을 참조하는 table을 만들었다. 테스트를 돌리면 table을 생성하는 과정에서 다음과 같은 쿼리를 확인할 수 있었다.
Hibernate: alter table solved add constraint FK3d1skgq7xw652uvo5mi5sbd26 foreign key (school_id) references school (id)
해결
결국 문제는 'Hibernate에게 어떻게 school_id를 참조하도록 강제하는가'였는데, 답은 간단했다. @JoinColumn에 referencedColumnName의 값으로 참조하길 원하는 필드 이름만 넣어주면 되는 것이다. 즉, Solved의 코드를 다음과 같이 수정하면 된다.
@Entity
public class Solved {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "school_id", referencedColumnName = "school_id")
private School school;
...
}
테스트를 돌려봤더니 아주 잘 작동한다.
Hibernate: alter table solved add constraint FK3d1skgq7xw652uvo5mi5sbd26 foreign key (school_id) references school (school_id)
왜 오류가 발생했나?
공식문서를 찾아보니 referencedColumnName의 기본값은 Primary Key라고 한다.
Default (only applies if single join column is being used): The same name as the primary key column of the referenced table.
내가 따로 값을 설정해주지 않아서 자동으로 PK를 참조하게 된 것이다. PK외에 다른 필드를 참조해야할 경우에는 반드시! 필드 이름을 넘겨줘야겠다.
여담
여기서 주의해야할 점이 한 가지 있는데, Hibernate의 오류(?)인지 이 경우 School이 Serializable을 implements해야 에러 없이 잘 작동한다. Hibernate 프로젝트에 이슈로 올라와있다.
참고링크
JPA JoinColumns 사용시 주의 사항 - Yoo Young-mo님
'공부방 > Spring' 카테고리의 다른 글
스프링 프레임워크의 등장 배경 (0) | 2023.04.23 |
---|---|
[Mysql] order by, group by (0) | 2023.01.10 |
deleteById, deleteByName (0) | 2022.09.30 |
[오류] FK가 PK가 아닌 다른 컬럼과 연관관계가 있을 때 (0) | 2022.08.31 |
다대다 연관관계 (1) | 2022.06.08 |