Entity 작성하면서 사용한 어노테이션

이동영·2025년 10월 27일

웹개발

목록 보기
19/36

JPA Entity란?

Entity는 데이터베이스 테이블을 그대로 옮겨놓은 Java 클래스이다.
예를 들어, 'User.java'라는 클래스를 만들고 '@Entity' 어노테이션을 붙이면, Spring Data JPA가 해당 클래스가 'User'테이블을 관리한다고 인식하게 된다.
Entity는 모든 비즈니스 로직(Service)과 데이터베이스 통신(Repository)의 가장 기본이 되는 모델이다.

어노테이션이란?

어노테이션은 다른 프로그램에게 유용한 정보를 제공하기 위해 사용되는 것으로 주석과 같은 의미를 가진다.
역할 :

  • 컴파일러에게 문법 에러를 체크하도록 정보를 제공
  • 프로그램을 빌드할 때 코드를 자동으로 생성할 수 있도록 정보를 제공
  • 런타임에 특정 기능을 실행하도록 정보를 제공

어노테이션은 @를 사용하여 작성하며, 해당 타겟에 대한 동작을 수행하는 프로그램 외에는 다른 프로그램에게 영향을 주지 않는다.

사용한 어노테이션

  1. 롬복(Lombok) - 편의 기능 : 코드를 간결하게 만들기 위해 사용한 기능이며, 이전에 velog에 정리하였던 기능이다.
    • @Getter : 모든 필드의 get...() 메소드를 자동으로 만들어준다.
    • @NoArgsConstructor(access = AccessLevel.PROTECTED) : 파라미터가 없는 기본 생성자(newUser())를 만든다.
      - JPA는 엔티티를 생성할 때 이 기본 생성자가 꼭 필요하다.
      - PROTECTED로 설정해서, 우리가 실수로 new User()를 직접 호출하는 것을 막고, @Builder를 사용하도록 유도한다.
    • @AllArgsConstructor(access = AccessLevel.PRIVATE) : 모든 필드를 받는 생성자를 만든다.
      - @Builder가 이 생성자를 사용하도록 하고, PRIVATE로 숨겨서 new 대신 빌더만 쓰도록 강제한다.
    • @Builder : User.builder().name("...").build()처럼 객체를 안전하고 깔끔하게 생성할 수 있는 빌더 패턴을 만들어 준다.
    • @Builder.Defalt : @Builder를 쓸 때, isPublic = false처럼 필드에 직접 할당한 기본값이 무시되지 않도록 보장해준다.
  2. JPA - 핵심 매핑 : 엔티티가 DB 테이블과 어떻게 연결되는지 정의하는 어노테이션이다.
    • @Entity: "이 Java 클래스는 데이터베이스 테이블과 매핑되는 엔티티입니다."라고 JPA에게 알려준다.
    • @Table(name = ""/USER"/") : "엔티티 이름은 'User'지만, 실제 DB 테이블 이름은 "USER"(대소문자 구분)입니다."처럼 DB 테이블 정보를 명시할 때 쓴다.
    • @MappedSuperClass : "이 클래스는 테이블이 아니지만, 이 클래스의 필드들을 상속받는 자식 엔티티에게 물려주세요."라는 뜻이다.
    • @Id : "이 필드가 테이블의 PK(기본키)입니다."
    • @GeneratedValue(strategy = GenerationType.IDENTITY) : "이 PK는 DB가 알아서 값을 증가시킵니다. (BIGSERIAL 또는 Auto-increment)"
    • @Column(name = "...") : "Java 필드(title)는 DB의 'TITLE'컬럼과 매핑됩니다."
      - nullable = false, unique = true, columnDefinition = "TEXT" 등 컬럼의 세부 속성을 정의할 때 쓴다.
    • @Enumerated(EnumType.STRING) : Role.ADMIN 같은 Enum(열거형) 타입을 DB에 저장할 때, 0, 1 같은 숫자가 아닌 "ADMIN"이라는 문자열로 저장하게 해준다.
  3. JPA - 관계 매핑 : 엔티티끼리(테이블끼리) 어떻게 관계를 정의한다.
    • @ManyToOne : "다 대 일 (N:1)" 관계. (ex. 많은 Post가 하나의 User에 속함)
    • @OneToMany(mappendBy = "...") : "일 대 다 (1:N)" 관계. (ex. 하나의 Post가 많은 Comment를 가짐)
      - mappedBy = "post" : "나는 주인이 아니야. 관계의 주인(FK(외래키)를 가진 쪽)은 'Comment' 엔티티의 'post' 필드야." (N+1 문제 해결에 중요)
    • @OneToOne : "일 대 일 (1:1)" 관계. (ex. 하나의 User는 하나의 MemberProfile을 가짐)
    • @JoinColumn(name = "USER_ID") : @ManyToOne이나 @OneToOne에서, "내가 가진 FK 컬럼 이름은 USER_ID입니다."라고 명시적으로 지정함
    • @MapsId : MemberProfile에서 "내 ID(@Id가 붙은 User)는 내 스스로 생성하는 게 아니라, @OneToOne 관계인 User의 ID 값을 그대로 가져와서 나의 PK이자 FK로 사용하겠습니다"라는 뜻이다.
  4. JPA - 감사(Auditing) 기능 : 엔티티가 생성/수정될 때 시간을 자동으로 기록한다.
    • @EntityListeners(AuditingEntityListener.class) : "이 Entity(혹은 이를 상속받는 자식)에 JPA Auditing 기능을 켜겠습니다."
    • @CreatedDate : "이 필드(createdAt)에는 엔티티가 처음 저장될 때의 시간을 자동으로 넣어주세요."
    • @LastModifiedDate : "이 필드(updatedAt)에는 엔티티가 수정될 때마다 시간을 자동으로 갱신해 주세요."
  5. JPA - 특수 기능 (논리 삭제 & 성능)
    • @SQLDelete(sql = "...") : "JPA가 delete()를 호출할 때, 실제 DELETE 쿼리 대신 내가 지정한 이 UPDATE 쿼리(SET DELETED_AT...)를 실행해주세요."
    • @Where(clause = "DELETED_AT IS NULL") : @SQLDelete와 세트이다. "이 엔티티에 대해 findAll(), findById() 등 모든 SELECT 쿼리를 실행할 때, 자동으로 'WHERE DELETED_AT IS NULL' 조건을 붙여서, 삭제된 데이터는 조회되지 않게 해주세요."
    • @DynamicUpdate : (성능 최적화) UPDATE 쿼리를 실행할 때, 엔티티의 모든 필드를 덮어쓰지 않고, 실제로 변경된 필드만 UPDATE 문에 포함시켜 준다.

0개의 댓글