본문 바로가기
springboot/jpa

JPA 클래스와 테이블 매핑 @Entity, @Table

by cactuslog 2025. 6. 22.

@Entity

@Entity
public class MemberEntity {
	...
}

 

●  해당 클래스가 JPA가 관리하는 엔티티임을 선언한다.

 

●  @Entity는 name 속성을 가지는데, 기본값을 쓰는게 좋다.

 

●  설정하지 않으면 기본 값으로 class명이 설정 된다.

 

Entity 선언 주의사항

1. 파라미터가 없는 기본 생성자 선언 필수 (public or protected)

●  JPA는 Reflection을 사용하여 객체를 생성한다.

 

●  실무에서는 protected를 주로 사용하는데, 외부에서 new로 직접 생성하는 것을 막고, JPA만 사용할 수 있어 캡슐화 유지에 유리하다.

 

2. final 클래스 사용 금지

public final class MemberEntity {
...
}

 

  JPA는 성능 최적화를 위해 지연 로딩을 사용한다.

Member member = em.find(Member.class, 1L); // 이 순간 DB에서 Team을 조회하고 싶지 않다.
Team team = member.getTeam().getName(); // team의 메소드가 호출될 때 DB에서 조회

 

  이 때 JPA는 Team 객체를 실제로 바로 만들지 않고, Team을 흉내 내는 proxy 객체를 만든다.

 

  Team 객체의 메소드가 호출될 때 DB에서 조회한다.

 

  프록시 객체를 만들려면 원본 클래스를 상속해야 한다.

 

●  자바에서 final 클래스는 상속이 불가능하기 때문에 Entity로 사용할 수 없다.

 

3. enum 사용 금지

●  enum은 자바가 내부적으로 final 클래스로 처리한다.

 

●  생성자도 private이고, 상속도 불가하여 JPA가 프록시 서브클래스로 생성하거나 동적으로 조작할 수 없다.

 

4. interface 사용 금지

●  JPA는 객체 생성 및 필드 접근까지 모두 해야하기 때문에 interface는 사용 불가하다.

 

5. inner class 사용 금지

public class Outer {
    public class Inner {
        // 이 내부 클래스는 Outer 인스턴스에 묶여 있다.
    }
}

 

●  JVM은 Inner 클래스의 생성자를 컴파일 타임에 아래처럼 생성한다.

public class Inner {
    public Inner(Outer outer) {}
}

 

●  외부 클래스 인스턴스(Outer) 가 있어야만 내부 클래스(Inner)를 만들 수 있다.

 

●  JPA는 기본 생성자를 리플렉션으로 호출하므로 외부 인스턴스 없이 newInstance 불가

 

●  따라서 JPA 스펙에서 금지하도록 다음과 같이 명시되어 있다.

 

●  The entity class must be a top-level class

 

6. 저장할 필드에 final 사용 금지

@Entity
public class Member {
    @Id
    private final Long id; // 금지
}

 

●  JPA는 객체를 생성한 후, 리플렉션을 이용해 필드 값을 직접 set 한다.

 

●  그런데 final 필드는 한 번 초기화되면 변경 불가능하므로, JPA가 값을 주입할 수 없다.


@Table

●  클래스와 DB 테이블 간 매핑을 상세하게 조정한다.

속성 기능
name 매핑할 테이블 이름
catalog 데이터베이스 catalog 매핑
schema 데이터베이스 schema 매핑
uniqueContraints DDL 생성 시에 유니크 제약 조건 생성

 

name 속성

@Table(name = "member")
@Entity
public class MemberEntity {
	...
}

 

●  생략하면 클래스명이 사용된다.

@Table
@Entity
public class MemberEntity {
	...
}

[Hibernate] 
    create table member_entity (
        id bigint not null,
        name varchar(255),
        user_desc varchar(255),
        primary key (id)
    )

 

●  camel case인 클래스명이 자동으로 snake case로 변경되어 DDL 쿼리가 나간다.

 

uniqueContraints 속성

●  복합 유니크 제약 조건을 지정할 수 있다.

 

●  단일 컬럼은 @Column(unique=true)로 가능하다.

@Column(unique = true)
private String email;

create table member (
        ...
        email varchar(255) unique,    
    )

 

●  2개 이상의 컬럼 조합에 대한 유니크 제약은 이 옵션을 통해서 해야 한다.

@Table(name = "member",
	uniqueConstraints = @UniqueConstraint(
	name = "uk_name_email",
	columnNames = {"name", "email"}
))
@Entity
public class MemberEntity {
	...
}

create table member (
        ...
        constraint uk_name_email unique (name, email)
    )

'springboot > jpa' 카테고리의 다른 글

JPA 기본키(PK) 매핑 전략  (0) 2025.06.23
JPA 필드와 컬럼 매핑  (0) 2025.06.23
JPA DB 스키마 자동 생성 이상과 현실  (0) 2025.06.22
JPA 영속성 관리  (1) 2025.06.20
JPA를 왜 사용해야 하는가?  (0) 2025.06.18