JAVA/이론

60. [ JAVA ] SpringBoot JPA @Entity 사용법

천재단미 2025. 1. 12. 02:32
728x90
반응형

 

 

 

 

 

 

@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);
}



 
728x90
반응형
home top bottom
}