@Entity 이란?
@Entity는 Java Persistence API (JPA)에서 사용되는 어노테이션으로, 데이터베이스의 테이블과 매핑될 Java 클래스를 나타냅니다.
1. 기본 사용법
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
2. @Entity 속성
@Entity(name = "UserEntity") // JPA에서 사용할 엔티티 이름 지정
- name: JPA에서 사용할 엔티티 이름을 지정. 기본값은 클래스 이름
3. 주요 어노테이션
3-1. @Table
@Data
@Entity
@Table(name = "users")
public class User {
참조
@Entity
@Table
name = "users", // 테이블 이름
uniqueConstraints = { // 유니크 제약조건
@UniqueConstraint(
name = "uk_user_email", // 제약조건 이름
columnNames = {"email"} // 제약조건 컬럼
)
},
indexes = { // 인덱스
@Index(
name = "idx_user_nickname", // 인덱스 이름
columnList = "nickname" // 인덱스 컬럼
)
}
)
public class User {
// ... } -
3-2. @Column
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
@Column(length = 100, unique = true)
public String email;
@Column(length = 256)
public String password;
@Column(length = 30)
public String nickname;
@Column
public Instant createdAt;
3-3. @Id와 @GeneratedValue
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
3-4. 연관관계 매핑
@OneToMany(mappedBy = "place") // Photo 클래스의 멤버변수 place 를 가르킨다.
public List<Photo> photoList = new ArrayList<>();
- 참조 -
// 일대다 관계
@OneToMany(
mappedBy = "user", // 양방향 관계에서 주인 지정
cascade = CascadeType.ALL, // 영속성 전파
fetch = FetchType.LAZY // 지연 로딩
)
private List<Order> orders = new ArrayList<>();
// 다대일 관계
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id") // 외래키 컬럼명
private User user;
// 일대일 관계
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id")
private Address address;
// 다대다 관계
@ManyToMany
@JoinTable(
name = "user_role", // 중간 테이블 이름
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles = new HashSet<>();
4. 엔티티 생명주기
아래와 같이 적용가능합니다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
// ... 필드 정의 ...
// 생성 시점에만 값이 설정되도록
@Column(updatable = false)
private Instant createdAt;
private Instant updatedAt;
// 영속화 이전
@PrePersist
public void prePersist() {
this.createdAt = Instant.now();
this.updatedAt = this.createdAt;
}
// 업데이트 이전
@PreUpdate
public void preUpdate() {
this.updatedAt = Instant.now();
}
}
5. 좋은 엔티티 설계 예시
@Data
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
@Column(length = 100, unique = true)
public String email;
@Column(length = 256)
public String password;
@Column(length = 30)
public String nickname;
@Column
public Instant createdAt;
@PrePersist
public void prePersist(){
createdAt = Instant.now();
}
}
6. 주의사항
6-1. @Entity 클래스는 기본 생성자가 필수 (JPA 규약)
JPA는 리플렉션을 통해 객체를 생성하므로 기본 생성자가 필요합니다. public 또는 protected 접근 제어자가 필수입니다.
6-2. 특정 클래스/구조에는 @Entity 사용 불가
final 클래스: 프록시 생성을 위한 상속이 불가능.
enum, interface: 테이블과 매핑할 수 없는 구조.
inner 클래스: 독립적인 생명주기를 가지지 않아 부적합.
6-3. 필드에 final 사용 불가
JPA는 엔티티 상태 변경을 지원하므로 필드에 final 사용 불가능.
6-4. @Column의 name 속성은 DB 컬럼명과 일치해야 함
엔티티와 테이블의 정확한 매핑을 위해 @Column의 name 속성은 실제 DB 컬럼명과 동일해야 합니다.
6-5. 지연 로딩(LAZY) 기본 사용, 즉시 로딩(EAGER)은 필요할 때만
지연 로딩(LAZY): 실제 사용 시점에 연관된 엔티티를 로딩.
즉시 로딩(EAGER): 항상 함께 사용되는 엔티티에 적합.
6-6. @OneToMany, @ManyToMany 관계에서 컬렉션 초기화
컬렉션 필드를 초기화하면 NPE 방지와 JPA 구현체의 효율적 관리 가능.
private List<Order> orders = new ArrayList<>();
6-7. 양방향 관계에서는 연관관계 편의 메소드 작성 권장
관계를 매핑할 때 한 쪽에서 관계 설정을 쉽게 관리하기 위해 편의 메소드 작성.
public void addOrder(Order order) {
this.orders.add(order);
order.setCustomer(this);
}
'JAVA > 이론' 카테고리의 다른 글
90. [ JAVA ] RestTemplate과 ResponseEntity의 차이와 활용법 (5) | 2025.01.19 |
---|---|
79. [JAVA] @OneToMany & @ManyToOne ?? (1) | 2025.01.15 |
54. [ JAVA ] Spring Boot에서 발생하는 예외처리(@Exception Hander) (0) | 2025.01.11 |
36. [ JAVA ] 배열 : HashMap (0) | 2024.12.17 |
35. [ JAVA ] 배열 : ArrayList (0) | 2024.12.17 |