해당 글에서는 Spring Boot JPA에서 엔티티 어노테이션 중 테이블 간의 관계에 사용되는 어노테이션에 대해 알아봅니다
💡 [참고] JPA 관련해서 구성 내용에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
분류 | 링크 |
Spring Boot Data JPA -1: ORM, JPA, Hibernate, QueryDSL 이론 | https://adjh54.tistory.com/421 |
Spring Boot Data JPA -2: 초기 환경 구성 + JpaRepository 활용 방법 | https://adjh54.tistory.com/422 |
Spring Boot Data JPA -3: 상세 JpaRepository 활용 방법 | https://adjh54.tistory.com/481 |
Spring Boot Data JPA 엔티티 어노테이션 -1 : 테이블 컬럼 단위 | https://adjh54.tistory.com/466 |
Spring Boot Data JPA 엔티티 어노테이션 -2 : 엔티티(테이블)간의 관계 | https://adjh54.tistory.com/477 |
Spring Boot Data JPA FetchType 이해하기 : 즉시/지연로딩 | https://adjh54.tistory.com/476 |
Spring Boot Data JPA + JPQL 활용 방법 | https://adjh54.tistory.com/479 |
Spring Boot Data JPA + Criteria API 활용 방법 | https://adjh54.tistory.com/483 |
Spring Boot Data JPA + QueryDSL 활용 방법-1 : 정의 및 구성요소 | https://adjh54.tistory.com/484 |
Spring Boot Data JPA + QueryDSL 활용 방법-2 : 초기 환경설정 및 활용예시 | https://adjh54.tistory.com/485 |
1) JPA 엔티티(Entity)
💡 JPA 엔티티(Entity)
- 데이터베이스의 테이블을 자바 클래스로 매핑하는 것을 의미합니다. 이 엔티티 클래스는 데이터베이스 테이블의 각 행을 표현하며, 클래스의 인스턴스는 특정 테이블의 한 행에 해당합니다.
- 데이터베이스 연산을 추상화하며 이를 통해 개발자는 SQL 쿼리에 의존하지 않고 데이터베이스와 상호작용할 수 있습니다. 이는 객체 지향 프로그래밍과 데이터베이스 간의 패러다임 불일치를 해결하는데 도움이 됩니다.
2) Entity 간의 관계 주요 어노테이션
💡 Entity 테이블 간의 관계 주요 어노테이션
- Entity 어노테이션 중에서 엔티티 간의 관계를 가지는 주요 어노테이션에 대해 알아봅니다.
1. 요약
어노테이션 | DB 매핑 타입 | 설명 |
@OneToOne | 1:1 관계 매핑 | 엔티티 간 1:1 관계를 정의합니다 |
@OneToMany | 1:N 관계 매핑 | 하나의 엔티티가 다른 엔티티와 1:N 관계를 가짐을 정의합니다 |
@ManyToOne | N:1 관계 매핑 | 하나의 엔티티가 다른 엔티티와 N:1 관계를 가짐을 정의합니다 |
@ManyToMany | N:N 관계 매핑 | 엔티티 간 N:N 관계를 정의합니다 |
@JoinColumns | 여러 외래키 컬럼 매핑 | 복합 키를 매핑할 때 사용합니다 |
@JoinColumn | 외래키 컬럼 매핑 | 외래키를 매핑할 때 사용합니다 |
@JoinTable | N:N 관계 매핑 | 엔티티 간의 N:N 관계를 가질 때 연결 테이블을 매핑할 때 사용합니다 |
3) 엔티티 어노테이션/속성 : 테이블 간의 관계
1. @OneToOne
💡 @OneToOne
- 테이블 간의 관계를 지정할 때 A 엔티티와 B 엔티티 간의 관계를 1:1 관계로 지정하는 데 사용하는데 어노테이션입니다.
- A 엔티티의 경우 하나의 row 데이터를 가지며, B 엔티티도 하나의 row 데이터를 가지는 구조입니다.
- 상황에 따라서 @OneToOne 어노테이션을 통해서 테이블 간의 INNER JOIN 또는 LEFT OUTER JOIN으로 구성될 수 있습니다.
1.1. @OneToOne 속성 및 속성값
속성 | 속성 타입 | 필수여부 | default | 설명 |
cascade | CascadeType | 선택 | 없음 | - 연관된 엔티티에 대해 특정 작업이 전파되도록 설정합니다. |
fetch | FetchType | 선택 | FetchType.EAGER | - 테이블 간의 연결 관계에서 EAGER을 통해 즉시 가져올지 LAZY를 통해 필요에 따라 가져올 지 전략을 설정합니다 |
mappedBy | String | 선택 | 없음 | - 양방향 연관관계에서 주인이 아닌 엔티티가 매핑을 위해 사용합니다. |
optional | boolean | 선택 | true | - 연관된 엔티티가 반드시 있어야 하는지 설정합니다. false일 경우, 연관된 엔티티는 반드시 있어야 합니다. |
orphanRemoval | boolean | 선택 | false | - 연관된 엔티티가 더 이상 관리되지 않을 때, 자동으로 삭제할지 설정합니다. |
targetEntity | Class | 선택 | 없음 | - 연관된 엔티티의 클래스를 명시적으로 지정합니다. |
OneToOne (Java(TM) EE 7 Specification APIs)
Specifies a single-valued association to another entity that has one-to-one multiplicity. It is not normally necessary to specify the associated target entity explicitly since it can usually be inferred from the type of the object being referenced. If the
docs.oracle.com
💡 Casecade & FetchType 속성 및 속성값
분류 | 속성 값 | 설명 |
Casecade | Casecade.ALL | 모든 변경(저장, 병합, 삭제, 재로딩)이 관련 엔티티에 적용됩니다. |
Casecade.DETACH | 엔티티가 detach 상태로 변경될 때, 관련 엔티티도 함께 변경됩니다. | |
Casecade.MERGE | 현재 엔티티의 상태를 데이터베이스에 반영할 때, 관련 엔티티도 함께 반영됩니다. | |
Casecade.PERSIST | 엔티티를 데이터베이스에 저장할 때, 관련 엔티티도 함께 저장됩니다. | |
Casecade.REFRESH | 엔티티를 데이터베이스로부터 새로운 정보로 갱신할 때, 관련 엔티티도 함께 갱신됩니다. | |
Casecade.REMOVE | 엔티티를 삭제할 때, 관련 엔티티도 함께 삭제됩니다 | |
FetchType | FetchType.LAZY | 엔티티가 실제로 사용될 때까지 데이터 로드를 연기합니다. |
FetchType.EAGER | 엔티티가 조회될 때 연관된 엔티티들도 함께 조회합니다. |
CascadeType (Java(TM) EE 7 Specification APIs)
All Implemented Interfaces: Serializable, Comparable public enum CascadeType extends Enum Defines the set of cascadable operations that are propagated to the associated entity. The value cascade=ALL is equivalent to cascade={PERSIST, MERGE, REMOVE, REFRESH
docs.oracle.com
💡 [참고] FetchType에 대해 궁금하시면 아래의 글이 도움이 됩니다.
[Java/JPA] Spring Boot JPA FetchType 이해하기: 즉시 로딩(Eager Loading) / 지연 로딩(Lazy Loading)
해당 글에서는 Spring Boot JPA 내에 테이블 간의 관계에서 사용되는 FetchType 중 즉시로딩, 지연 로딩에 대해 알아봅니다. 1) FetchType 💡 FetchType - JPA에서 엔티티를 조회할 때 연관된 ‘엔티티 조회 방
adjh54.tistory.com
1.2. @OneToOne 사용예시

💡 사용예시
- @OneToOne 관계에서 사용자 엔티티(tb_user)와 여권 엔티티(tb_passport)의 관계가 있다고 가정합니다.
- 한 사람은 하나의 여권을 가질 수 있고, 여권도 한 사람에게만 발급이 되는 구조입니다.
- 데이터베이스의 테이블 관점에서 볼 때 사용자 테이블(tb_user)과 여권 테이블(tb_passport) 테이블 사이에 1:1 관계이며 이를 @OneToOne 어노테이션을 이용하여 관계를 구성합니다.
@Entity
@Table(name = "tb_user")
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_sq")
private long userSq;
@Column(name = "user_nm")
private String userNm;
@Column(name = "passport_id")
private long passportId;
@OneToOne
private PassportEntity passportEntity;
}
@Entity
@Table(name = "tb_passport")
public class PassportEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "passport_id")
private Long passportId;
// 여권번호
@Column(name = "passport_num")
private String passportNum;
// 발급일
@Column(name = "issue_date")
private String issueDate;
// 만료일
@Column(name = "expired_date")
private String expiredDate;
}
💡 결과 화면
- 해당 SQL에서는 FetchType을 EAGER로 지정한 UserEntity를 조회한 상태입니다.
- 해당 상황에서는 @OneToOne 상태로 지정되었기에 tb_user 테이블을 기준으로 여권 테이블이 Join 되어서 하나의 여권의 테이블이 조회됩니다. (* Left Join으로 수행이 되어서 tb_user 테이블 값만 존재하더라도 조회가 됩니다.)

1.3. @OneToOne으로 LEFT JOIN을 INNER JOIN으로 변경 사용예시
💡@OneToOne으로 LEFT JOIN을 INNER JOIN으로 변경 사용예시
- @JoinColmn 어노테이션을 추가하였습니다
- @OneToOne 속성으로 optional = false를 추가합니다. optinal 속성은 기본적으로 true이며 연관된 엔티티가 반드시 있어야 하는지 설정합니다. false일 경우, 연관된 엔티티는 반드시 있어야 합니다
@Entity
@Getter
@Table(name = "tb_user")
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_sq")
private long userSq;
@Column(name = "user_nm")
private String userNm;
@Column(name = "passport_id")
private long passportId;
@OneToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "passport_id", insertable = false, updatable = false)
private PassportEntity passportEntity;
}

2. @OneToMany
💡 @OneToMany
- 테이블 간의 관계를 지정할때 A 엔티티와 B 엔티티 간의 관계를 1 : N 관계로 지정하는 데 사용하는 어노테이션입니다.
- A 엔티티의 경우는 하나의 row 데이터를 가지고, B 엔티티 같은 경우는 여러 개의 row 데이터를 가지는 구조입니다.
- 해당 어노테이션은 '하나의 row 데이터를 가지고 있는 쪽'에서 사용됩니다.
2.1. @OneToMany 속성 및 속성값
속성 | 속성타입 | 필수여부 | default | 설명 |
cascade | CascadeType | 선택 | 없음 | 연관된 엔티티에 대해 특정 작업이 전파되도록 설정합니다. |
fetch | FetchType | 선택 | FetchType.EAGER | 테이블 간의 연결 관계에서 EAGER을 통해 즉시 가져올지 LAZY를 통해 필요에 따라 가져올 지 전략을 설정합니다 |
mappedBy | String | 선택 | 없음 | 양방향 연관관계에서 주인이 아닌 엔티티가 매핑을 위해 사용합니다. |
orphanRemoval | boolean | 선택 | false | 연관된 엔티티가 더 이상 관리되지 않을 때, 자동으로 삭제할지 설정합니다. |
targetEntity | Class | 선택 | 없음 | 연관된 엔티티의 클래스를 명시적으로 지정합니다. |
OneToMany (Java(TM) EE 7 Specification APIs)
Specifies a many-valued association with one-to-many multiplicity. If the collection is defined using generics to specify the element type, the associated target entity type need not be specified; otherwise the target entity class must be specified. If the
docs.oracle.com
💡 Casecade & FetchType 속성 및 속성값
분류 | 속성 값 | 설명 |
Casecade | Casecade.ALL | 모든 변경(저장, 병합, 삭제, 재로딩)이 관련 엔티티에 적용됩니다. |
Casecade.DETACH | 엔티티가 detach 상태로 변경될 때, 관련 엔티티도 함께 변경됩니다. | |
Casecade.MERGE | 현재 엔티티의 상태를 데이터베이스에 반영할 때, 관련 엔티티도 함께 반영됩니다. | |
Casecade.PERSIST | 엔티티를 데이터베이스에 저장할 때, 관련 엔티티도 함께 저장됩니다. | |
Casecade.REFRESH | 엔티티를 데이터베이스로부터 새로운 정보로 갱신할 때, 관련 엔티티도 함께 갱신됩니다. | |
Casecade.REMOVE | 엔티티를 삭제할 때, 관련 엔티티도 함께 삭제됩니다 | |
FetchType | FetchType.LAZY | 엔티티가 실제로 사용될 때까지 데이터 로드를 연기합니다. |
FetchType.EAGER | 엔티티가 조회될 때 연관된 엔티티들도 함께 조회합니다. |
CascadeType (Java(TM) EE 7 Specification APIs)
All Implemented Interfaces: Serializable, Comparable public enum CascadeType extends Enum Defines the set of cascadable operations that are propagated to the associated entity. The value cascade=ALL is equivalent to cascade={PERSIST, MERGE, REMOVE, REFRESH
docs.oracle.com
2.2. @OneToMany 사용예시
💡 사용예시
- @OneToMany 관계에서 사용자 엔티티(tb_user)와 주문 엔티티(tb_order)의 관계가 있다고 가정합니다.
- 한 사람은 여러 개의 주문을 할 수 있는 구조입니다.
- 데이터베이스의 테이블 관점에서 볼때 사용자 테이블(tb_user)과 주문 테이블(tb_order) 테이블 사이에는 1 : N 관계이며 이를 @OneToMany 어노테이션을 이용하여 관계를 구성합니다.

@Entity
@Getter
@Table(name = "tb_user")
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_sq")
private long userSq;
@Column(name = "user_nm")
private String userNm;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "userInfo")
private List<OrderEntity> orderEntity;
}
@Entity
@Table(name = "tb_order")
public class OrderEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "order_sq")
private long orderSq;
@Column(name = "order_nm")
private String orderNm;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_sq")
private UserEntity userInfo;
}
💡 결과 화면
- 해당 SQL에서는 EAGER으로 지정한 UserEntity를 조회한 상태입니다.
- 해당 상황에서는 FetchType.EAGER으로 UserEntity 조회시 OrderEntity를 함께 조회하는 식으로 수행이 됩니다. 또한, @OneToMany 상태로 지정되었기에 하나의 사용자 테이블의 모든 주문 테이블 정보가 조회되는 Left Join이 수행이 됩니다.

3. @ManyToOne
💡 @ManyToOne
- 테이블 간의 관계를 지정할때 A 엔티티와 B 엔티티 간의 관계를 N : 1 관계로 지정하는 데 사용하는 어노테이션입니다.
- A 엔티티의 경우 여러개의 row 데이터를 가지고 B 엔티티의 경우 하나의 데이터를 가지는 구조입니다.
- 해당 어노테이션은 '여러개의 row 데이터를 가지고 있는 쪽'에서 사용됩니다.
3.1. @ManyToOne 속성 및 속성값
속성 | 속성 타입 | 필수여부 | default | 설명 |
cascade | CascadeType | 선택 | 없음 | 연관된 엔티티에 대해 특정 작업이 전파되도록 설정합니다. |
fetch | FetchType | 선택 | FetchType.EAGER | 테이블 간의 연결 관계에서 EAGER을 통해 즉시 가져올지 LAZY를 통해 필요에 따라 가져올 지 전략을 설정합니다 |
optional | boolean | 선택 | true | 연관된 엔티티가 반드시 있어야 하는지 설정합니다. false일 경우, 연관된 엔티티는 반드시 있어야 합니다. |
targetEntity | Class | 선택 | 없음 | 연관된 엔티티의 클래스를 명시적으로 지정합니다. |
ManyToOne (Java(TM) EE 7 Specification APIs)
Specifies a single-valued association to another entity class that has many-to-one multiplicity. It is not normally necessary to specify the target entity explicitly since it can usually be inferred from the type of the object being referenced. If the rela
docs.oracle.com
💡 Casecade & FetchType 속성 및 속성값
분류 | 속성 값 | 설명 |
Casecade | Casecade.ALL | 모든 변경(저장, 병합, 삭제, 재로딩)이 관련 엔티티에 적용됩니다. |
Casecade.DETACH | 엔티티가 detach 상태로 변경될 때, 관련 엔티티도 함께 변경됩니다. | |
Casecade.MERGE | 현재 엔티티의 상태를 데이터베이스에 반영할 때, 관련 엔티티도 함께 반영됩니다. | |
Casecade.PERSIST | 엔티티를 데이터베이스에 저장할 때, 관련 엔티티도 함께 저장됩니다. | |
Casecade.REFRESH | 엔티티를 데이터베이스로부터 새로운 정보로 갱신할 때, 관련 엔티티도 함께 갱신됩니다. | |
Casecade.REMOVE | 엔티티를 삭제할 때, 관련 엔티티도 함께 삭제됩니다 | |
FetchType | FetchType.LAZY | 엔티티가 실제로 사용될 때까지 데이터 로드를 연기합니다. |
FetchType.EAGER | 엔티티가 조회될 때 연관된 엔티티들도 함께 조회합니다. |
CascadeType (Java(TM) EE 7 Specification APIs)
All Implemented Interfaces: Serializable, Comparable public enum CascadeType extends Enum Defines the set of cascadable operations that are propagated to the associated entity. The value cascade=ALL is equivalent to cascade={PERSIST, MERGE, REMOVE, REFRESH
docs.oracle.com
3.2. @ManyToOne 사용예시
💡 사용예시
- @ManyToOne 관계에서는 여러 주문 정보와 하나의 사용자 정보가 있다고 가정합니다.
- 여러 개의 주문을 할 수 있는 사람은 한 사람이다라는 구조입니다.
- 데이터베이스의 테이블 관점에서 볼 때는 주문 테이블(tb_order)과 사용자 테이블(tb_user) 사이에는 N : 1 관계이며 @ManyToOne 어노테이션을 이용하여 관계를 구성합니다.
@Entity
@Getter
@Table(name = "tb_user")
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_sq")
private long userSq;
@Column(name = "user_nm")
private String userNm;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userInfo")
private List<OrderEntity> orderEntity;
}
@Entity
@Table(name = "tb_order")
public class OrderEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "order_sq")
private long orderSq;
@Column(name = "order_nm")
private String orderNm;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_sq")
private UserEntity userInfo;
}
💡 결과 화면
- 해당 SQL에서는 EAGER으로 지정한 OrderEntity를 조회한 상태입니다.
- 해당 상황에서는 @ManyToOne 상태로 지정되었기에 하나의 사용자 테이블의 모든 주문 테이블 정보가 조회되는 Left Join이 수행이 됩니다.

4. @ManyToMany
💡 @ManyToMany
- 테이블 간의 관계를 지정할때 A 엔티티와 B 엔티티 간의 관계를 N : M 관계로 지정하는 데 사용하는 어노테이션입니다.
- A 엔티티의 경우 여러개의 row 데이터를 가지고 B 엔티티 역시 여러 개의 row 데이터를 가지고 있는 구조입니다.
- 해당 어노테이션은 '여러개의 row 데이터를 가지고 있는 어느 쪽'에서든 사용됩니다.
4.1. @ManyToMany 속성 및 속성값
속성 | 속성타입 | 필수여부 | default | 설명 |
cascade | CascadeType | 선택 | 없음 | 연관된 엔티티에 대해 특정 작업이 전파되도록 설정합니다. |
fetch | FetchType | 선택 | FetchType.EAGER | 테이블 간의 연결 관계에서 EAGER을 통해 즉시 가져올지 LAZY를 통해 필요에 따라 가져올 지 전략을 설정합니다 |
optional | boolean | 선택 | true | 연관된 엔티티가 반드시 있어야 하는지 설정합니다. false일 경우, 연관된 엔티티는 반드시 있어야 합니다. |
targetEntity | Class | 선택 | 없음 | 연관된 엔티티의 클래스를 명시적으로 지정합니다. |
ManyToMany (Java(TM) EE 7 Specification APIs)
Specifies a many-valued association with many-to-many multiplicity. Every many-to-many association has two sides, the owning side and the non-owning, or inverse, side. The join table is specified on the owning side. If the association is bidirectional, eit
docs.oracle.com
💡 Casecade & FetchType 속성 및 속성값
분류 | 속성값 | 설명 |
Casecade | Casecade.ALL | 모든 변경(저장, 병합, 삭제, 재로딩)이 관련 엔티티에 적용됩니다. |
Casecade.DETACH | 엔티티가 detach 상태로 변경될 때, 관련 엔티티도 함께 변경됩니다. | |
Casecade.MERGE | 현재 엔티티의 상태를 데이터베이스에 반영할 때, 관련 엔티티도 함께 반영됩니다. | |
Casecade.PERSIST | 엔티티를 데이터베이스에 저장할 때, 관련 엔티티도 함께 저장됩니다. | |
Casecade.REFRESH | 엔티티를 데이터베이스로부터 새로운 정보로 갱신할 때, 관련 엔티티도 함께 갱신됩니다. | |
Casecade.REMOVE | 엔티티를 삭제할 때, 관련 엔티티도 함께 삭제됩니다 | |
FetchType | FetchType.LAZY | 엔티티가 실제로 사용될 때까지 데이터 로드를 연기합니다. |
FetchType.EAGER | 엔티티가 조회될 때 연관된 엔티티들도 함께 조회합니다. |
CascadeType (Java(TM) EE 7 Specification APIs)
All Implemented Interfaces: Serializable, Comparable public enum CascadeType extends Enum Defines the set of cascadable operations that are propagated to the associated entity. The value cascade=ALL is equivalent to cascade={PERSIST, MERGE, REMOVE, REFRESH
docs.oracle.com
4.2. @ManyToMany 사용예시
💡 사용예시
- @ManyToMany 관계에서는 여러 사용자와 여러 수업 간의 정보가 있다고 가정합니다.
- 한 사용자는 여러 개의 수업을 참여할 수 있고, 하나의 수업에는 여러 학생이 참여할 수 있는 구조입니다.
- 데이터베이스의 테이블 관점에서 볼 때는 사용자 테이블(tb_user)과 수업 테이블(tb_course) 사이에 다대다 관계를 두는 사용자 수업 맵(tb_user_course_map)을 두고 N:N 관계이며 @ManyToMany 어노테이션을 이용하여 관계를 구성합니다.

@Entity
@Getter
@Table(name = "tb_user")
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private long userId;
@Column(name = "user_nm")
private String userNm;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "tb_user_course_map",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private List<CourseEntity> courses = new ArrayList<>();
}
@Entity
@Getter
@Table(name = "tb_course")
public class CourseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "course_id")
private long courseId;
@Column(name = "course_nm")
private String courseNm;
@ManyToMany(mappedBy = "courses")
private List<UserEntity> students = new ArrayList<>();
}
💡 결과화면
- 해당 SQL에서는 EAGER으로 지정한 UserEntity를 조회한 상태입니다.
- 해당 상황에서는 @ManyToMany 상태로 지정되었기에 사용자 테이블(tb_user)을 기준으로 사용자 수업 맵 테이블(tb_user_course_map)과 조인하며 수업 테이블(tb_course) 테이블을 조인하여 최종 N:N 관계이며 @ManyToMany 어노테이션을 이용하여 구성되었습니다.

5. @JoinColumn
💡 @JoinColumn
- 테이블간의 관계에서 왜래키(FK)를 매핑하는 용도로 사용되는 어노테이션을 의미합니다.
- 주로 @ManyToOne, @OneToOne 어노테이션과 같이 사용이 됩니다.
5.1. @JoinColumn 속성 및 속성 값
속성 | 속성타입 | 필수여부 | default | 설명 |
columnDefinition | String | 선택 | “” | 컬럼의 SQL 선언을 지정하는데 사용되는 속성 |
foreignKey | ForeignKey | 선택 | “” | 외래 키 제약 조건을 지정하는데 사용되는 속성 |
unique | boolean | 선택 | false | 고유 제약 조건을 설정하는데 사용되는 속성 |
insertable | boolean | 선택 | true | 삽입이 가능한지 여부를 지정하는데 사용되는 속성 |
updatable | boolean | 선택 | true | 업데이트 가능한지 여부를 지정하는데 사용되는 속성 |
nullable | boolean | 선택 | true | null 값을 허용하는지 여부를 지정하는데 사용되는 속성 |
name | String | 선택 | “” | 컬럼명을 지정하는데 사용되는 속성 |
referencedColumnName | String | 선택 | “” | 참조하는 외래 키 컬럼명을 지정하는데 사용되는 속성 |
table | String | 선택 | “” | 외래 키를 매핑한 테이블 이름을 지정하는데 사용되는 속성 |
JoinColumn (Java(TM) EE 7 Specification APIs)
(Optional) The name of the foreign key column. The table in which it is found depends upon the context. If the join is for a OneToOne or ManyToOne mapping using a foreign key mapping strategy, the foreign key column is in the table of the source entity or
docs.oracle.com
💡 [참고] ForeignKey 속성 및 속성 값
속성 | 속성타입 | 필수여부 | default | 설명 |
foreignKeyDefinition | String | 선택 | “” | 외래키 제약조건을 직접 정의하는 기능을 제공합니다. |
name | String | 선택 | “” | 외래키의 이름을 지정하는 기능을 제공합니다. |
value | ConstraintMode | 선택 | “” | 외래키 제약조건의 활성화, 비활성화를 설정하는 기능을 제공합니다. |
ForeignKey (Java(TM) EE 7 Specification APIs)
(Optional) Used to specify whether a foreign key constraint should be generated when schema generation is in effect. A value of CONSTRAINT will cause the persistence provider to generate a foreign key constraint. If the foreignKeyDefinition element is not
docs.oracle.com
💡 [참고] ConstraintMode 속성 및 속성 값
속성 값 | 설명 |
ConstraintMode.CONSTRAINT | 제약 조건을 적용합니다. 이는 관계형 데이터베이스에서 무결성을 유지하기 위한 규칙을 설정하는데 사용됩니다. |
ConstraintMode.NO_CONSTRAINT | 제약 조건을 적용하지 않습니다. 이는 관계형 데이터베이스에서 무결성을 유지하기 위한 규칙을 설정하지 않는데 사용됩니다. |
ConstraintMode.PROVIDER_DEFAULT | JPA 제공자의 기본 제약 조건 설정을 사용합니다. 이는 JPA 구현체가 제공하는 기본 설정을 따르는데 사용됩니다. |
5.2. @JoinColumn 사용예시
💡 @JoinColumn 사용예시
- 해당 사용예시에서는 @OneToOne와 함께 사용되고 있습니다.
- UserEntity와 PassportEntity 간의 1:1 조인을 하는 관계에서 passport_id 컬럼 값과 조인을 수행합니다.
- 기본적으로 passport_id와 UserEntity에서는 기본 키(user_sq) 값과 조인이 수행됩니다.
@Entity
@Getter
@Table(name = "tb_user")
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_sq")
private long userSq;
@Column(name = "user_nm")
private String userNm;
@Column(name = "passport_id")
private long passportId;
@OneToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "passport_id", insertable = false, updatable = false)
private PassportEntity passportEntity;
}
[ 더 알아보기 ]
💡 기본적으로 왜래키와 ID가 되는 컬럼이 조인이 된다고 하면, 내가 특정 컬럼을 지정할 수 있는 방법은 없는 건가?
- 아닙니다. @JoinColumn의 속성 중 referencedColumnName를 이용하여 참조할 키를 지정할 수 있습니다.
@JoinColumn(name = "passport_id", referencedColumnName = "id")
6. @JoinColumns
💡 @JoinColumns
- 엔티티 간의 관계를 매핑할 때 사용이 되는 어노테이션입니다. 해당 어노테이션은 주로 '복합 키'를 사용하는 다대다 관계를 표현할 때 사용됩니다.
- @JoinColumn 어노테이션을 배열로 가지고 있으며, 두 테이블이 더 많은 컬럼으로 조인되어야 할 때 사용됩니다.
- 하나의 컬럼을 나타내며, 이를 통해 복수의 컬럼을 사용하여 테이블 간의 관계를 정의할 수 있습니다.
- @JoinColumns 어노테이션은 @OneToMany, @ManyToOne, @OneToOne, @ManyToMany와 같은 다른 관계 어노테이션과 함께 사용될 수 있습니다.
6.1. @JoinColumns 속성 및 속성 값
속성 | 속성타입 | 필수여부 | default | 설명 |
value | JoinColumn[] | 필수 | [] | JoinColumn 어노테이션의 배열. 이를 통해 여러 개의 조인 컬럼을 지정할 수 있습니다. |
JoinColumns (Java(TM) EE 7 Specification APIs)
Specifies the mapping for composite foreign keys. This annotation groups JoinColumn annotations for the same relationship. When the JoinColumns annotation is used, both the name and the referencedColumnName elements must be specified in each such JoinColum
docs.oracle.com
6.2. @JoinColumns 사용예시
💡 @JoinColumns 사용예시
- 해당 예시에서는 OneEntity 엔티티에서 OtherEntity 엔티티를 조인하고 있습니다. 조인 대상은 first_id, second_id 값을 가집니다.
@Entity
@Table(name = "tb_one")
public class OneEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "first_id")
private String firstId;
@Column(name = "second_id")
private String secondId;
@ManyToOne
@JoinColumns({
@JoinColumn(name = "first_id", referencedColumnName = "first_id", insertable = false, updatable = false),
@JoinColumn(name = "second_id", referencedColumnName = "second_id", insertable = false, updatable = false)
})
private OtherEntity otherEntity;
}
💡 JoinColumn 속성 및 속성 값
속성 | 속성타입 | 필수여부 | default | 설명 |
columnDefinition | String | 선택 | “” | 컬럼의 SQL 선언을 지정하는데 사용되는 속성 |
foreignKey | ForeignKey | 선택 | “” | 외래 키 제약 조건을 지정하는데 사용되는 속성 |
unique | boolean | 선택 | false | 고유 제약 조건을 설정하는데 사용되는 속성 |
insertable | boolean | 선택 | true | 삽입이 가능한지 여부를 지정하는데 사용되는 속성 |
updatable | boolean | 선택 | true | 업데이트 가능한지 여부를 지정하는데 사용되는 속성 |
nullable | boolean | 선택 | true | null 값을 허용하는지 여부를 지정하는데 사용되는 속성 |
name | String | 선택 | “” | 컬럼명을 지정하는데 사용되는 속성 |
referencedColumnName | String | 선택 | “” | 참조하는 외래 키 컬럼명을 지정하는데 사용되는 속성 |
table | String | 선택 | “” | 외래 키를 매핑한 테이블 이름을 지정하는데 사용되는 속성 |
JoinColumn (Java(TM) EE 7 Specification APIs)
(Optional) The name of the foreign key column. The table in which it is found depends upon the context. If the join is for a OneToOne or ManyToOne mapping using a foreign key mapping strategy, the foreign key column is in the table of the source entity or
docs.oracle.com
7. @JoinTable
💡 @JoinTable
- 관계형 데이터베이스의 '중간 테이블'을 정의하는 데 사용되는 어노테이션입니다. 주로 다대다 관계에서 사용되며 두 엔티티 사이의 매핑을 위한 중간테이블을 정의합니다.
7.1. @JoinTable 속성 및 속성 값
속성 | 속성타입 | 필수여부 | default | 설명 |
name | String | 선택 | “” | 이름을 지정합니다. |
catalog | String | 선택 | “” | 카탈로그를 지정합니다. |
schema | String | 선택 | “” | 스키마를 지정합니다. |
joinColumns | JoinColumn[] | 선택 | {} | 조인 컬럼을 지정합니다. |
inverseJoinColumns | JoinColumn[] | 선택 | {} | 반대 방향의 조인 컬럼을 지정합니다. |
foreignKey | ForeignKey | 선택 | ConstraintMode.CONSTRAINT | 외래 키를 지정합니다. |
indexes | Index[] | 선택 | {} | 인덱스를 지정합니다. |
inverseForeignKey | ForeignKey | 선택 | ConstraintMode.PROVIDER_DEFAULT | 반대 방향의 외래 키를 지정합니다. |
uniqueConstraints | UniqueConstraint[] | 선택 | {} | 고유 제약 조건을 지정합니다. |
JoinTable (Java(TM) EE 7 Specification APIs)
Specifies the mapping of associations. It is applied to the owning side of an association. A join table is typically used in the mapping of many-to-many and unidirectional one-to-many associations. It may also be used to map bidirectional many-to-one/one-t
docs.oracle.com
💡 JoinColumn, ForeignKey 속성 및 속성 값
분류 | 속성 | 속성타입 | 필수여부 | default | 설명 |
JoinColumn | columnDefinition | String | 선택 | “” | 컬럼의 SQL 선언을 지정하는데 사용되는 속성 |
foreignKey | ForeignKey | 선택 | “” | 외래 키 제약 조건을 지정하는데 사용되는 속성 | |
unique | boolean | 선택 | false | 고유 제약 조건을 설정하는데 사용되는 속성 | |
insertable | boolean | 선택 | true | 삽입이 가능한지 여부를 지정하는데 사용되는 속성 | |
updatable | boolean | 선택 | true | 업데이트 가능한지 여부를 지정하는데 사용되는 속성 | |
nullable | boolean | 선택 | true | null 값을 허용하는지 여부를 지정하는데 사용되는 속성 | |
name | String | 선택 | “” | 컬럼명을 지정하는데 사용되는 속성 | |
referencedColumnName | String | 선택 | “” | 참조하는 외래 키 컬럼명을 지정하는데 사용되는 속성 | |
table | String | 선택 | “” | 외래 키를 매핑한 테이블 이름을 지정하는데 사용되는 속성 | |
ForeignKey | foreignKeyDefinition | String | 선택 | “” | 외래키 제약조건을 직접 정의하는 기능을 제공합니다. |
name | String | 선택 | “” | 외래키의 이름을 지정하는 기능을 제공합니다. | |
value | ConstraintMode | 선택 | “” | 외래키 제약조건의 활성화, 비활성화를 설정하는 기능을 제공합니다. |
JoinColumn (Java(TM) EE 7 Specification APIs)
(Optional) The name of the foreign key column. The table in which it is found depends upon the context. If the join is for a OneToOne or ManyToOne mapping using a foreign key mapping strategy, the foreign key column is in the table of the source entity or
docs.oracle.com
💡 [참고] ConstraintMode 속성 및 속성 값
속성 값 | 설명 |
ConstraintMode.CONSTRAINT | 제약 조건을 적용합니다. 이는 관계형 데이터베이스에서 무결성을 유지하기 위한 규칙을 설정하는데 사용됩니다. |
ConstraintMode.NO_CONSTRAINT | 제약 조건을 적용하지 않습니다. 이는 관계형 데이터베이스에서 무결성을 유지하기 위한 규칙을 설정하지 않는데 사용됩니다. |
ConstraintMode.PROVIDER_DEFAULT | JPA 제공자의 기본 제약 조건 설정을 사용합니다. 이는 JPA 구현체가 제공하는 기본 설정을 따르는데 사용됩니다. |
7.2. @JoinTable 사용예시
💡 @JoinTable 사용예시
- 아래의 예시에서는 tb_user, tb_course라는 테이블 간의 N:N 관계를 형성하고 있습니다.
- 이때에 중간 테이블인 tb_user_course_map 테이블이라는 중간 map 테이블을 둡니다.
- 기준이 되는 tb_user 테이블에서는 user_id를 이용하며 tb_course 테이블에서는 course_id를 이용하여 중간테이블을 구성하며 참조합니다.

@Entity
@Getter
@Table(name = "tb_user")
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private long userId;
@Column(name = "user_nm")
private String userNm;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "tb_user_course_map",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private List<CourseEntity> courses = new ArrayList<>();
}
오늘도 감사합니다. 😀