본 글은 JPA Entity에서의 양방향 관계에 대해서 공부한 지식을 정리한 글입니다.
서론
JPA Entity클래스는 데이터베이스의 레코드를 객체로 매핑하는 역할을 합니다. 객체로 매핑하는 어노테이션에는 다음과 같은 어노테이션이 있습니다.
- N:1 ➡️ @ManyToOne
- 1:N ➡️ @OneToMany
- 1:1 ➡️ @OneToOne
- N:M ➡️ @ ManyToMany
다음 예시에서 음식과 고객의 관계를 살펴보겠습니다.
음식
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
고객
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user")
private List<Food> foodList = new ArrayList<>();
}
양방향 관계는 두 Entity가 서로를 참조할 수 있는 관계입니다. 즉, "User" Entity가 "Food" Entity를 참조하고, 반대로 Food Entity도 User를 참조할 수 있습니다.
그러나 User Entity에서 Food Entity의 정보를 참조하지 않는다면, Food 데이터를 조회하는 방법이 없습니다.
이를 해결하기 위해 List<Food>와 같은 컬렉션을 사용하여 User Entity에서 Food Entity를 참조합니다.
그런데 Entity에 대한 개념이 정확히 잡혀있지 않아 궁금한점이 생겼습니다.
Entity클래스에서는 다른 클래스를 주입받지 않았는데 어떻게 매핑을 할 수 있는거지❓
위 같은 궁금점이 생겼습니다. 이에 대해 더 알아보았습니다.
JPA Entity 클래스와 의존성 주입
JPA Entity 클래스는 다음과 같은 특징을 가지고 있습니다.
- 직접 의존성 주입 없음
- Entity 클래스는 Spring의 의존성 주입 컨테이너와
직접적으로 연결되지 않습니다. - JPA는 Entity를 데이터베이스와 매핑하고, 객체 간의 관계를 설정합니다.
- Entity 클래스는 Spring의 의존성 주입 컨테이너와
- Entity의 상태 관리
- Entity는 JPA의 EntityManager가 관리합니다.
- EntityManager는 CRUD 작업을 수행하며, 엔티티 객체의 상태를 관리합니다.
- 생성자와 Getter/Setter
- Entity 클래스는 기본 생성자와 getter/setter 메서드를 갖추고 있습니다.
- 이는 JPA가 객체를 생성하고 데이터를 주입하기 위해 필요하지만,
외부 의존성을 주입받지는 않습니다.
정리하자면, 관계 매핑 어노테이션이 없더라도 자바 코드 내에서 엔터티 클래스 간의 참조(필드 선언)는 가능합니다. 하지만 이 경우 두 클래스 간에 자바 객체 수준에서의 연결만 있을 뿐, JPA가 이를 인식하고 데이터베이스에 반영하지는 않습니다.
자바 코드 내 참조
public class User {
private Long id;
private String name;
private List<Food> foodList; // 단순한 자바 객체 참조
// Getter 및 Setter
}
public class Food {
private Long id;
private String name;
private double price;
private User user; // 단순한 자바 객체 참조
// Getter 및 Setter
}
관계 매핑 어노테이션이 없어도 자바 코드에서 엔터티 클래스 간의 참조(필드 선언)는 가능합니다. 이 경우 두 클래스 간에 자바 객체 수준에서의 연결이 있을 뿐입니다.
JPA 관리 및 데이터베이스 반영
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id") // 외래 키 설정
private User user;
// Getter 및 Setter
}
이처럼 JPA의 @ManyToOne 및 @JoinColumn 어노테이션을 통해 관계를 매핑하면, 외래 키가 생성되고 JPA가 자동으로 SQL 쿼리를 생성하여 데이터베이스에서 두 엔터티 간의 관계를 관리하게 됩니다.
Entity클래스에서는 다른 클래스를 주입받지 않았는데 어떻게 매핑을 할 수 있는거지❓
즉 위의 궁금점에 대한 답은 다음과 같습니다.
결론적으로, 엔티티 클래스 간의 참조는 의존성 주입의 개념과는 다르고, 엔티티 클래스 간의 참조는 데이터베이스의 외래 키(Foreign Key) 관계를 모델링하는 것입니다.
JPA와 같은 ORM 프레임워크는 이러한 참조를 바탕으로 데이터베이스에서 엔티티 간의 관계를 관리하고, 이를 통해 객체 간의 관계를 데이터베이스의 관계와 일치시키는 것입니다.
따라서, 엔티티 간의 참조는 순수한 자바 객체의 참조일 뿐이고, JPA가 이를 데이터베이스의 외래 키 관계로 매핑하여 관리합니다. 이 과정에서 의존성 주입은 필요하지 않으며, 대신 JPA가 이 참조를 기반으로 데이터베이스에서 관계를 처리합니다.
한마디로 정리하자면 다음과 같습니다.
Entity 클래스 간의 참조는의존성 주입이 아니라, JPA가 데이터베이스의 외래 키 관계를 모델링하고 관리하는 것
'TIL,일일 회고' 카테고리의 다른 글
[TIL, 일일 회고] 2024.08.25 - 랜덤 시크릿 키 생성 방법 (openssl rand) (0) | 2024.08.25 |
---|---|
[TIL, 일일 회고] 2024.08.24 - 외래 키 주인❗️ (1) | 2024.08.24 |
[TIL, 일일 회고] 2024.08.22 - assertThrows란 무엇일까❓: 예외를 테스트하는 효과적인 방법 (0) | 2024.08.22 |
[TIL, 일일 회고] 2024.08.21 - 비관적 락(Pessimistic Lock)으로도 업데이트 손실이 발생하는 이유 (0) | 2024.08.21 |
[TIL, 일일 회고] 2024.08.20 - Referer헤더란❓ (0) | 2024.08.20 |