[JPA] @JoinColumns 두 개 이상의 조인 컬럼 설정하기
Entity 연관 관계 설정을 하다보면,
두 개 이상의 조인 관계를 나타내야하는 경우가 있다.
만약에 서비스 사용자(Member)와 게시글(Board) Entity가 존재하고,
게시글은 사용자의 고유 아이다(id)와 이름(name) 을 외래키(foreign key)로 가지고 있다고 해보자.
Member와 Board는 1:N 의 관계를 가질때,
Entity 는 아래와 같이 구성할 수 있을 것이다.
1. 구현
[Entity] Member.class
@Entity
@NoArgsConstructor
@Getter
@ToString
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column
private Integer age;
@Builder
public Member(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
[Entity] Board.class
@Entity
@NoArgsConstructor
@Getter
@ToString
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String title;
@Column
private String content;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumns({
@JoinColumn(name = "member_id", referencedColumnName = "id"),
@JoinColumn(name = "member_name", referencedColumnName = "name")
})
private Member member;
@Builder
public Board(Long id, String title, String content, Member member) {
this.id = id;
this.title = title;
this.content = content;
this.member = member;
}
}
Board 클래스에 Member 클래스의 연관관계를 표기할 때,
@JoinColumns() 어노테이션을 이용하면 두 가지 이상의 컬럼을 연결 할수있다.
- name : board 테이블에 표기될 member 테이블 컬럼 이름을 표기
- referencedColumnName : member 테이블에 정의된 컬럼 이름
2. 실행
애플리케이션을 실행 시켜 DB에 스키마 생성(create) 시키면,
아래 이미지처럼 2개의 컬럼이 FK 로 연결된 걸 볼 수 있다.
저장된 데이터를 조회 시,
Board 테이블 조회와 같이 join table로 Member 테이블의 id와 name 값을 기준으로 조회하는 것을 볼 수 있다.
3. 추가
구현 상 어려운 점은 없을 건데....
여기서 드는 궁금증!
'FetchType을 Lazy로 Member 조회 없이 가져오는가?' 였다.
그래서 Fetch Type 을 Lazy 로 바꾸고 조회를 진행해 보았다.
진행 결과,
FetchType.Lazy 로 설정하여도 Member의 name 컬럼을 찾아야하기에,
한번 더 Member를 select 하는 쿼리가 나가는 것을 볼 수있었다.
만약 컬럼이 하나만 연결되었다면
(If, Member id 컬럼)
해당 객체를 호출하지 않는 이상 Member를 조회하지 않았겠지만
연결된 컬럼이 name 도 포함되어있기에 함께 조회되는 것을 볼 수 있었다.
Jpa 연관관계 설계 상,
디폴트 값이 아래와 같이 설정 되어 있다.
ToOne 은 Fetch Eager
ToMany 는 Fetch Lazy
굳이 ManyToOne 에서 Lazy 를 하는 경우가 아니라면 조회에 문제는 없겠지만
혹시 여러 컬럼을 연결하고,
Lazy 로 설정하여 쿼리가 두번 나가고 있지는 않는지 점검해보는건 어떨까한다.
4. 참고 문서
https://stackoverflow.com/questions/56327228/avoid-jpa-fetch-eager-with-join-table
Avoid jpa fetch eager with join table
I have the next classes: A class User: @Entity @JsonRootName(value = "user") @Table(name = "web_users", schema = "t_dw_comercial") public class User { @Id private int userId; private S...
stackoverflow.com