@JoinColumn?
@JoinColumn
은 연관관계를 갖는 객체의 FK에 대한 설정을 할 때 사용된다.
@JoinColumn
이 사용될 때 연관 관계 타입(ex. @OneToOne
, @OneToMany
)에 따라 FK가 어디에 생성되는 지와 @JoinColumn
의 속성을 확인해보자.
편의상 참조하는 쪽의 엔티티를 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;
}
Station
은 Line
객체를 필드로 가지고 있으며, Line
을 참조하고 있다. 이 때 SourceEntity
는 Station
이 되고, TargetEntity
는 Line
이 된다.
@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
의 속성매핑할 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
테이블에 생성된다.
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)
FK 제약 조건을 직접 지정할 수 있다. 이 속성은 테이블을 생성할 때만 사용한다.
@Entity
@Table(name = "station")
public class Station {
...
@ManyToOne(nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private Line line;
}
null값 허용 여부를 설정한다.
@Entity
@Table(name = "station")
public class Station {
...
@ManyToOne(nullable = false)
private Line line;
}
unique 여부를 설정한다.
@Entity
@Table(name = "station")
public class Station {
...
@ManyToOne(unique = true)
private Line line;
}