Spring/강의

[📙 숙련 Spring] 3-2. JPA Entity 만들기

가지코딩 2025. 5. 21. 00:16

📙 목차

  1. @Entity
  2. @Table
  3. DDL 자동 생성 (hibernate.hbm2ddl.auto)
  4. EntityManager를 사용한 JPA 실행 예
  5. 필드 매핑
  6. 기본 키(PK)
  7. 연관관계 Mapping

1. @Entity

@Entity

  • JPA가 관리하는 Entity 클래스임을 선언하는 어노테이션이다.
  • 반드시 기본 생성자와 PK(@Id) 필드를 포함해야 한다.
  • 클래스명과 동일한 이름이 Entity 이름 기본값이며, @Entity(name = "CustomName")으로 변경 가능하다.
  • 사용할 수 없는 대상: final, enum, interface, inner 클래스, 그리고 final 필드.
@Entity(name = "Tutor") // 기본 값, name 속성은 생략하면 된다.
@Table(name = "tutor")
public class Tutor {

    // PK
    @Id
    private Long id;

    // 필드
    private String name;

    // 기본 생성자
    public Tutor() {
    }

    public Tutor(Long id, String name) {
        this.id = id;
        this.name = name;
    }
}

 


2. @Table

@Table

  • Entity가 매핑될 DB 테이블 정보를 지정한다.
  • 주요 속성:
    • name: 테이블 이름 (기본값은 Entity 이름)
    • catalog, schema: DB 카탈로그 및 스키마 지정
    • uniqueConstraints: 유니크 제약조건 설정
@Entity
@Table(name = "tutor")
public class Tutor {
}

3. DDL 자동 생성 (hibernate.hbm2ddl.auto)

DDL 자동 생성 (hibernate.hbm2ddl.auto)

  • JPA가 Entity 기반으로 DB 테이블을 자동 생성/수정하는 옵션.
  • application.properties 에서 사용
hibernate.hbm2ddl.auto=create

 

 

DDL 자동 생성 속성

설명
create 기존 테이블 삭제 후 새로 생성
create-drop create 후 애플리케이션 종료 시 테이블 삭제
update 변경사항만 반영 (기존 컬럼 삭제는 하지 않음)
validate 매핑 검증만 수행, 불일치 시 예외 발생
none 자동 생성 기능 사용 안 함

 

 

* 실무: 개발 시 create나 update 사용, 운영 환경에선 validate 또는 none 권장.

 

 

DDL 자동생성 제약조건 설정

  • DDL을 자동으로 생성할 때만 사용되며 Application 로직에는 영향이 없다.
어노테이션 주요 속성 역할  적용 시점
@Column unique, nullable, length 컬럼 단위 제약조건 설정 DDL 생성 시
@Table uniqueConstraints 테이블 단위 유니크 제약조건 설정 DDL 생성 시

 


4. EntityManager를 사용한 JPA 실행 예

엔티티 정의

@Entity
public class Member {
    @Id
    private Long id;
    private String name;

    // 기본 생성자 (JPA 요구)
    public Member() {}

    public Member(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    // Getter, Setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

 

 

EntityManager 사용

public class JpaExample {

    private static final EntityManagerFactory emf = 
        Persistence.createEntityManagerFactory("myPersistenceUnit");

    public static void main(String[] args) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin();

            // 1. 엔티티 저장 (Persist)
            Member member = new Member(1L, "홍길동");
            em.persist(member);

            // 2. 엔티티 조회 (Find)
            Member findMember = em.find(Member.class, 1L);
            System.out.println("조회한 회원 이름 = " + findMember.getName());

            // 3. 엔티티 수정 (변경 감지)
            findMember.setName("홍길순");

            // 4. 엔티티 삭제
            // em.remove(findMember);

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            e.printStackTrace();
        } finally {
            em.close();
        }

        emf.close();
    }
}

5. 필드 매핑

필드 매핑

  • Entity의 필드는 DB 컬럼에 매핑된다.
  • 어노테이션 사용 없이도 필드 이름과 컬럼명이 같으면 자동 매핑된다.
  • 컬럼 이름과 필드 이름을 다르게 하려면 @Column(name = "db_column_name") 사용.
@Column(name = "title")
private String bigTitle;

 

 

사용되는 어노테이션

어노테이션 설명
@Column 컬럼 매핑, 제약 조건 지정
@Temporal 날짜 타입 지정 (DATE, TIME, TIMESTAMP)
@Enumerated Enum 타입 매핑 (EnumType.STRING 권장)
@Transient DB 컬럼 매핑 제외 필드
@Lob tinyText, 큰 용량 문자열 또는 바이너리 매핑

 

 

@Column 속성

속성 설명 Default
name 객체 필드와 매핑할 테이블의 컬럼 이름 객체 필드 이름
nullable DDL 생성 시 null 값의 허용 여부 설정 true(허용)
unique DDL 생성 시 하나의 컬럼에 유니크 제약조건을 설정  
columnDefinition DDL 생성 시 데이터베이스 컬럼 정보를 직접 설정할 수 있다.  
length DDL 생성 시 문자 길이 제약조건 설정 단, String만 사용 가능 255
insertable 설정된 컬럼의 INSERT 가능 여부 true
updatable 설정된 컬럼의 UPDATE 가능 여부 true

 


6. 기본 키(PK)

JPA에서는 엔티티를 정의할 때 기본 키(PK)를 반드시 지정해야 한다.

 

사용되는 Annotation

  • @Id
    • 엔티티의 필드를 기본 키로 지정할 때 사용한다.
    • 직접 값을 수동으로 설정할 수 있다.
@Entity
public class Tutor {

    @Id
    private Long id;

    ...
}
 
  • @GeneratedValue
    • 기본 키 값을 자동으로 생성하도록 설정할 때 사용한다.
    • 전략(strategy)을 지정하여 다양한 방식의 자동 생성이 가능하다.
@Entity
public class Tutor {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    ...
}

 

 

기본 키 생성 전략 (GenerationType)

전략 설명 비고
IDENTITY 데이터베이스가 자동 생성 (MySQL, PostgreSQL의 AUTO_INCREMENT) em.persist() 시점에 즉시 insert 실행
SEQUENCE 시퀀스 객체 사용 (Oracle 등) @SequenceGenerator 필요
TABLE 별도의 키 생성 테이블 사용 @TableGenerator 필요
AUTO DB Dialect에 따라 자동 지정 (기본값) MySQL이면 IDENTITY 사용

 

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "tutor_seq", sequenceName = "tutor_seq", allocationSize = 1)
private Long id;

7. 연관관계 Mapping

연관관계 Mapping

  • 객체 간의 관계를 데이터베이스의 외래 키 관계에 맞춰 매핑하는 작업

 

연관관계 종류

관계 타입 설명 어노테이션
단방향 연관관계 한 쪽만 참조 @ManyToOne, @OneToOne, 등
양방향 연관관계 서로 참조 (객체 그래프 탐색 가능) mappedBy 사용

 

 

연관관계 주요 어노테이션

어노테이션 설명
@ManyToOne 다대일 (N:1)
@OneToMany 일대다 (1:N)
@OneToOne 일대일 (1:1)
@ManyToMany 다대다 (N:M)
@JoinColumn 외래 키 매핑
mappedBy 연관관계의 주인 아닌 쪽 지정 시 사용

 

 

연관관계의 주인(Owner)

  • DB의 외래 키(Foreign Key)를 관리하는 엔티티
  • 연관관계의 주인만이 연관관계를 변경할 수 있는 권한을 가진다.
  • 주인이 아닌 쪽(mappedBy)은 읽기 전용이다.
  • 항상 FK가 있는 곳을 연관관계의 주인으로 지정한다.

 

예제: Member - Team (N:1 양방향 연관관계)

@Entity
public class Member {

    @Id @GeneratedValue
    private Long id;

    private String name;

    @ManyToOne
    @JoinColumn(name = "team_id") // 연관관계의 주인 (외래 키 소유)
    private Team team;
}
@Entity
public class Team {

    @Id @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "team") // 주인이 아님 (읽기 전용)
    private List<Member> members = new ArrayList<>();
}