naspeciallist 2025. 5. 6. 23:33

 

본 글은 https://www.inflearn.com/course/ORM-JPA-Basic/dashboard 강의를 바탕으로 작성한 글입니다.

 

1. 엔티티 매핑이란?


 

JPA에서 가장 중요한 두가지중 하나인 엔티티 매핑입니다. 엔티티 매핑은 객체와 관계형 데이터 베이스를 어떻게 매핑을 해서 사용하는지에 대한 설계적인 측면에서 가장 중요하다고 할 수 있습니다.

 

앤티티를 매핑할 때는 다음과 같은 어노테이션을 이용하게 됩니다.

 

객체와 테이블 매핑 : @Entity, @Table

필드와 컬럼 매핑 : @Column

기본 키 매핑 : @Id

연관관계 매핑: @ManyToOne, @JoinColumn

 

 

2. @Entity


 

@Entity가 붙은 클래스는 JPA가 관리하는 엔티티 입니다. JPA를 사용해서 테이블과 매핑할 클래스는 @Entity를 필수적으로 붙여야합니다. @Entity 어노테이션이 붙게 되면 데이터베이스의 테이블에 대응이 되며, JPA는 이 클래스를 통해 테이블에 데이터를 저장하고 조회합니다.

 

@Entity가 붙은 클래스는 기본생성자가 필수 입니다. JPA는 내부적으로 프록시를 생성하거나 리플렉션을 통해 객체를 생성합니다. 이때 파라미터가 없는 public 또는 protected 생성자가 반드시 있어야 합니다. private은 안 됩니다.

 

final클래스, enum, interface, inner클래스는 사용이 불가능합니다.

final클래스를 사용하게 되면 프록시 생성이 불가능해져서 JPA를 사용할 수 없게 됩니다. 또한 enum, interface, inner클래스는 엔티티로 사용이 불가능합니다.

데이터베이스에 저장할 필드는 JPA가 값을 넣을 수 있어야 하기 때문에  final사용이 불가능합니다.

 

아래 코드와 같이 JPA에서 관리 할 엔티티를 간단하게 어노테이션으로 지정할 수 있습니다.

@Entity
@Table(name = "MBR")
public class Member {

}

 

@Table 어노테이션을 이용하여 엔티티와 메핑할 테이블을 지정할 수 있습니다. 만약에 테이블을 다른 이름을 매핑하고 싶을 때 위의 코드처럼 @Table(name = )을 이용할 수 있습니다. 예를 들어 회사 내규에 의해 “MBR”이라는 축약형을 사용해야 할 때 @Table(name = “MBR”)을 통해서 테이블의 이름을 MBR로 매핑할 수 있습니다.

생략하면 클래스 이름이 그대로 테이블 이름으로 사용됩니다.

 

이렇게 하면 실제 insert쿼리가 나갈 때 insert into mbr로 나가게 됩니다. 조회할 때도 마찬가지로 select * from mbr 이렇게 나가게 됩니다.

 

 

 

3. DDL 생성 기능


 

JPA가 매핑 정보만 보면 어떤 쿼리를 만들어야 할 지 어떤 테이블인지 다 알수 있습니다. 그래서 jpa는 애플리케이션 로딩 시점에 db테이블을 생성하는 기능을 지원해줍니다. 물론 이런 기능은 운영단계 보단 개발 단계나 로컬 pc에서 개발할 때만 사용해야 합니다.

 

애플리케이션 실행 시점에서 DDL구문을 실행 시켜 자동으로 스키마를 생성 합니다. 보통은 저희가 개발을 할 때 테이블을 먼저 만들어 놓고 객체로 돌아가서 개발을 하게 되는데  JPA를 사용하게 되면 그럴 필요가 없게 됩니다. 객체에서 매핑을 통해 개발을 해놓으면 이제 애플리케이션을 쓸 때 필요한 테이블을 다 자동으로 생성이 됩니다. 특히 JPA를 활용하면 각 데이터베이스에 맞는 방언을 이용하여 각 데이터베이스에 맞는 적절한 DDL을 생성해 줍니다. 이렇게 생성된 DDL은 개발 장비에서만 사용해야 합니다. 운영서버에서 사용되기에는 불안한 측면이 있기 때문에 적절히 다듬은 후 운영서버에서 사용하게 됩니다.

 

hibernate.hbm2ddl.auto 라는 옵션을 이용하여 데이터베이스 스키마의 자동생성 속성을 조정할 수 있습니다. 스키마 자동생성 속성에는 총 5가지가 있습니다.

1. create : 기존테이블 삭제 후 다시 생성 (DROP + CREATE)
2. create-drop : create와 같으나 종료시점에 테이블 DROP
3. update : 변경분만 반영(운영DB에는 사용하면 안됨)
4. validate : 엔티티와 테이블이 정상 매핑되었는지만 확인
5. none : 사용하지 않음

 

create로 설정을 하게 되면 애플리케이션을 재시작 했을 때 기존테이블을 삭제 한 뒤 테이블을 다시 생성하게 됩니다. 이 설정을 통해 테이블의 컬럼 추가나 컬럼 삭제 등을 자유롭게 설정 할 수 있습니다.

 

create-drop를 이용하게 되면 create 처럼 테이블을 생성을 하나 삭제 시점이 재시작 때가 아닌 애플리케이션이 종료 될 때 테이블을 삭제 합니다. 이런 옵션은 테스트 케이스를 실행시켰을 때 테스트 마지막에 깔끔하게 초기화 시키고 싶을 때 보통 사용을 합니다.

 

update를 이용하게 되면 애플리케이션을 재시작 했을 때 변경분만 반영이 되게 됩니다. 예를 들어 create로 설정을 한 뒤 애플리케이션을 재시작하게 되면 테이블이 drop을 통해 삭제 된 뒤 다시 create문을 통해 스키마가 생성이 됩니다. 하지만 update를 이용하면 애플리케이션을 재시작 할 시 alter문을 이용하여 테이블 변경과정만 거치게 됩니다. 이 방법을 이용하면 스키마에 데이터를 보존 할 수 있으나 이미 추가된 컬럼이 삭제가 되지 않는다는 단점이 있습니다.

 

validate로 설정을 하게 되면 엔티티와 테이블이 정상으로 매핑이 되는지 확인을 하게 됩니다. 만약에 컬럼명이 변경이 되어 제대로 매핑이 안되있으면 오류가 발생하여 애플리케이션이 실행되지 않게 됩니다.

 

none으로 설정을 하게 되면 스키마 자동생성을 사용하지 않게 됩니다.

 

데이터베이스 스키마 자동생성 시 다음과 같이 주의할 점들이 있습니다.

  1. 운영 장비에는 절대 create, create-drop, update 사용하면안된다.
  2. 개발 초기 단계는 create 또는 update
  3. 테스트 서버는 update 또는 validate
  4. 스테이징과 운영 서버는 validate 또는 none

운영장비에는 절대 create, create-drop, update를 사용하면 안됩니다. 개발 초기 단계는 create 또는 Update로 해서 로컬과 개발서버에서 사용을 해도 됩니다. 이제 개발 초기에는 테스트 서버에다가 create 또는 Update를 사용해서 쓰면 되는데 어느정도 개발이 진행되고 나서는 update또는 validate를 사용하면 됩니다. 여기서 테스트 서버는 개발 서버나 여러명의 개발자가 함께 사용하는 중간서버 입니다. 여기서는 create를 쓰면 데이터가 다 날라가게 됩니다. 그래서 테스트 할 때는 update나 validate정도를 사용하는걸 권장합니다. 스테이징과 운영서버에는 validate또는 none을 사용해야 합니다. 특히 운영서버에서 update를 사용하게 되면 alter를 이용하여 데이터가 변경이 되었을 때 운영단계에는 몇천건 이상의 데이터를 변경해야 하기 때문에 alter가 자동으로 사용이 되면 시스템에 장애가 일어나게 됩니다.

 

4.DDL 생성기능을 통한 제약조건 설정


 

DDL 생성 기능을 통해 제약조건을 추가할 수 있습니다. 예를 들어 회원 이름은 필수로 하고 10자를 초과하지 않게 할려면 다음과 같은 어노테이션을 이용하여 제약조건을 추가 할 수 있습니다.

 @Column(nullable = false, length = 10)
 private String name;

 

이 제약조건 설정은 DDL을 자동 생성할 때만 적용됩니다.

JPA 실행 로직에는 영향을 주지 않으며, JPA는 여전히 null 값을 가진 객체를 저장하려 시도할 수 있습니다.

따라서 비즈니스 로직 수준에서의 유효성 검사는 별도로 수행해야 합니다. (예: @NotNull, @Size 등의 Bean Validation 사용)