다대일
01 Jan 2019다대일 단방향 구현
회원에서 팀을 참조해야 하고 팀에서 회원을 참조할 필요가 없다면 단방향 연관 관계로 구현할 수 있다.
회원 엔티티
@Entity
class Member(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MEMBER_ID")
val id: Long = 0L,
val username: String,
@ManyToOne
@JoinColumn(name = "TEAM_ID")
val team: Team
)
팀 엔티티
@Entity
class Team(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "TEAM_ID")
val id: Long = 0L,
val name: String
)
생성된 DDL(h2 기준)
create table member (
member_id bigint generated by default as identity,
username varchar(255),
team_id bigint,
primary key (member_id)
);
create table team (
team_id bigint generated by default as identity,
name varchar(255),
primary key (team_id)
);
alter table member
add constraint FKcjte2jn9pvo9ud2hyfgwcja0k
foreign key (team_id)
references team
@ManyToOne 속성
| 속성 | 기능 | 기본값 |
|---|---|---|
| optional | 연관된 엔티티가 필수값인가 | true |
| fetch | 패치 전략 설정 | FetchType.EAGER |
| cascade | 영속성 전이 설정 |
@JoinColumn
외래키를 매핑할 때 사용한다.
생략하면 기본 전략을 사용한다.
| 속성 | 기능 | 기본값 |
|---|---|---|
| name | 매핑할 외래 키 이름 | 필드명 + _ + 참조하는 테이블의 기본 키 칼럼명(위 예시의 경우 team_team_id) |
다대일 양방향 구현
회원 엔티티와 생성된 DDL은 단방향과 동일하다.
팀 엔티티에 OneToMany 애노테이션만 추가하면 된다.
팀 엔티티
@Entity
class Team(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "TEAM_ID")
val id: Long = 0L,
val name: String,
@OneToMany(mappedBy = "team")
val members: List<Member>
)
@OneToMany의 mappedBy속성
연관관계의 주인
엔티티를 양방향 연관관계로 설정하면 객체의 참조는 둘인데 외래 키는 하나다.
두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야 하는데 관리하는 엔티티를 연관관계의 주인이라 한다.
mappedBy속성은 연관관계의 주인을 지정하는 속성이다.
다대일, 일대다 관계에서는 항상 다 쪽이 외래 키를 가지므로 회원이 외래 키를 가지고 연관관계의 주인이 된다.
위 예시에서 mappedBy = “team”의 team은 Member 엔티티의 team 필드를 의미한다.
양방향 연관관계의 주의점
- 양쪽 모두 관계를 맺어주자.
- 기존에 맺어진 연관관계가 있다면 제거해야 한다.
- 양방향 매핑 시에는 무한 루프에 빠지지 않게 조심해야 한다.