다대일

다대일 단방향 구현

회원에서 팀을 참조해야 하고 팀에서 회원을 참조할 필요가 없다면 단방향 연관 관계로 구현할 수 있다.

회원 엔티티

@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 필드를 의미한다.

양방향 연관관계의 주의점