Spring Data JPA에서는 두 엔티티 간의 다대다(Many-to-Many
) 관계를 설정할 때 @ManyToMany
어노테이션을 사용한다. 이 관계를 설정할 때는 중간에 연결 테이블을 사용해 두 엔티티를 연결하는데, 이러한 개념은 알아도 실제로 적용하는 법을 모를 때가 종종 있다.
이번 포스트에서는 실제로 @ManyToMany
와 @JoinTable
어노테이션을 사용하여 다대다 관계를 설정하는 방법과 작동 방식에 대해 설명해 보도록 하겠다.
☝️ 한 작가가 여러 책을 쓸 수 있고, 하나의 책에도 여러 작가가 존재할 수 있다.
다대다(Many-to-Many) 관계: 하나의 엔티티 인스턴스가 여러 엔티티 인스턴스와 연관되고, 반대로 여러 엔티티 인스턴스가 또 다른 엔티티 인스턴스와 연관되는 관계이다.
연결 테이블: 두 엔티티 간의 다대다 관계를 관리하기 위해 사용하는 중간 테이블이다.
ChatRoom
엔티티ChatRoom
엔티티는 채팅방을 나타내며, 여러 사용자가 참여할 수 있다.
@Entity
public class ChatRoom {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "chat_room_name", nullable = false, unique = true)
private String chatRoomName;
@ManyToMany
@JoinTable(
name = "user_chat_room",
joinColumns = @JoinColumn(name = "chat_room_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private Set<User> users = new HashSet<>();
}
User
엔티티User
엔티티는 사용자를 나타내며, 여러 채팅방에 참여할 수 있습니다.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
@ManyToMany(mappedBy = "users") // "users"는 ChatRoom 엔티티에서 정의한 필드명
private Set<ChatRoom> chatRooms = new HashSet<>();
}
여기서는 예시를 위해 ChatRoom
이라는 채팅방과 User
라는 엔티티를 사용할 것이다. 사용자는 여러 채팅방에 참여할 수 있고, 하나의 채팅방에는 여러 유저가 들어올 수 있다.
다음으로는 여기서 사용된 어노테이션과 주요 속성에 대해 알아보자.
@JoinTable
어노테이션@JoinTable
은 두 엔티티 간의 다대다 관계를 설정할 때 사용되는 연결 테이블 어노테이션이다. 이 어노테이션은 연결 테이블의 이름과 컬럼을 정의한다.
name
: 연결 테이블의 이름을 지정한다.joinColumns
: 현재 엔티티의 기본 키가 연결 테이블에서 어떤 컬럼과 매핑될지를 정의한다.inverseJoinColumns
: 연관된 엔티티의 기본 키가 연결 테이블에서 어떤 컬럼과 매핑될지를 정의한다.@ManyToMany @JoinTable( name = "user_chat_room", // 연결 테이블의 이름 // ChatRoom 엔티티의 기본 키 joinColumns = @JoinColumn(name = "chat_room_id"), // User 엔티티의 기본 키 inverseJoinColumns = @JoinColumn(name = "user_id") ) private Set<User> users = new HashSet<>();
joinColumns
은 ChatRoom
엔티티의 id
와 연결 테이블의 chat_room_id
를 매핑한다.inverseJoinColumns
은 User
엔티티의 id
와 연결 테이블의 user_id
를 매핑한다.user_chat_room
연결 테이블컬럼명 | 데이터 타입 | 설명 |
---|---|---|
chat_room_id | BIGINT | ChatRoom 테이블의 ID (외래키) |
user_id | BIGINT | User 테이블의 ID (외래키) |
연결 테이블 생성: JPA는 ChatRoom
과 User
사이에 user_chat_room
이라는 연결 테이블을 생성하여, 두 테이블 간의 관계를 관리한다.
컬럼 매핑: chat_room_id
컬럼은 ChatRoom
엔티티의 기본 키(id
)와 연결되며, user_id
컬럼은 User
엔티티의 기본 키(id
)와 연결된다.
양방향 연관: ChatRoom
엔티티는 users
필드를 통해 참여하는 사용자들을 참조하고, User
엔티티는 chatRooms
필드를 통해 참여하는 채팅방을 참조한다.
다대다, 일대다, 일대일 관계 등을 제대로 알긴 했지만 실제로 JPA
에서 사용하려고 하면 순간 머뭇거릴 때가 있었다. 이 기회에 제대로 DB의 연결 관계에 대해서 공부하고, 더 익숙해지려고 한다. 특히 실전 경험이 중요한 만큼 열심히 이번 프로젝트에서 써봐야겠다!