@JoinColumn

hongo·2023년 7월 11일
0

@JoinColumn?

@JoinColumn은 연관관계를 갖는 객체의 FK에 대한 설정을 할 때 사용된다.

@JoinColumn이 사용될 때 연관 관계 타입(ex. @OneToOne, @OneToMany)에 따라 FK가 어디에 생성되는 지와 @JoinColumn의 속성을 확인해보자.

SourceEntity와 TargetEntity

편의상 참조하는 쪽의 엔티티를 SourceEntity, 참조되는 엔티티를 TargetEntity라고 정의하겠다.

예시를 봐보자. 지하철의 역과 노선을 나타내는 Station클래스와 Line클래스가 존재한다.

// SourceEntity: 필드 line으로 Line 엔티티를 참조함

@Entity
@Table(name = "station")
public class Station {
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id;

    @Column(nullable = false)
    private String name;

    @ManyToOne
    private Line line;
}
// TargetEntity, Station에 의해 참조당함


@Entity
@Table(name = "line")
public class Line {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;
}

StationLine객체를 필드로 가지고 있으며, Line을 참조하고 있다. 이 때 SourceEntityStation이 되고, TargetEntityLine이 된다.

연관 관계 타입에 따라 FK가 생기는 위치

  • @OneToOne & @ManyToOne

    • SourceEntity에 FK가 생성된다.
  • 조인 테이블을 사용하는 양방향 @OneToMany, @ManyToOne, @ManyToMany

    • 조인 테이블에 FK가 생성된다.

      line_stations와 같이 조인테이블을 통해 연결이 되었다면, 이 테이블에 FK가 생성된다.

  • 단방향 @OneToMany

    • TargetEntity에 FK가 생성된다.

    이 경우, name 속성을 통해 FK의 이름을 정해주지 않으면 sourceEntity에 있는 참조 객체의 변수명 + "_" 참조 객체의 PK 컬럼명으로 이름이 생성된다. @OneToMany의 경우 참조 객체의 변수명을 stations와 같이 복수명으로 작성할 것이다. 이 경우 FK의 이름이 stations_id와 같은 형태로 생성되므로, 이게 싫다면 name을 통해 이름을 지정해주어야 한다.

@JoinColumn의 속성

name

매핑할 FK의 이름에 대한 속성이다.

디폴트 값은 참조하는 객체 필드명 + "_" + 참조하는 테이블의 기본키 컬럼명으로 설정된다.

예시로 확인해보자. 지하철의 노선과 역을 나타내는 Line객체와 Station객체가 존재한다.

@Entity
@Table(name = "line")
public class Line {
    ...
}
@Entity
@Table(name = "station")
public class Station {
	...

    @ManyToOne
    private Line line;
}

현재 @JoinColumn의 name을 사용해 FK의 이름을 설정하지 않은 상태이다.

이럴 경우, FK를 가지는 쪽의 객체(Station)에서 정의된 참조되는 객체(Line)의 이름 + "_" + 참조되는 테이블(Line)의 DB PK 컬렴명을 합친 이름이 FK의 이름이 된다. 위 예시의 경우 line_id라는 이름의 FK가 Station테이블에 생성된다.

referencedColumnName

FK가 참조하는 TargetEntity의 컬럼명을 지정한다.

기본값은 참조하는 테이블의 PK이다.

@Entity
@Table(name = "station")
public class Station {
	...

    @ManyToOne(referencedColumnName = "name") // Line의 name필드가 FK로 등록됨
    private Line line;
}
create table station (
    id bigint generated by default as identity,
    name varchar(255) not null,
    line_name varchar(255), # FK line_name이 생성됨
    stations_id bigint,
    primary key (id)
)

alter table station 
add constraint FK8e94tc2n5x5k5wyu4e3636j56 
foreign key (line_name) 
references line (name)

foreignKey(DDL 관련)

FK 제약 조건을 직접 지정할 수 있다. 이 속성은 테이블을 생성할 때만 사용한다.

@Entity
@Table(name = "station")
public class Station {
	...

    @ManyToOne(nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
    private Line line;
}

nullable(DDL 관련)

null값 허용 여부를 설정한다.

@Entity
@Table(name = "station")
public class Station {
	...

    @ManyToOne(nullable = false)
    private Line line;
}

unique(DDL 관련)

unique 여부를 설정한다.

@Entity
@Table(name = "station")
public class Station {
	...

    @ManyToOne(unique = true) 
    private Line line;
}

참고

0개의 댓글