개발서적/자바 ORM 표준 JPA

[자바 ORM 표준 JPA 프로그래밍] 4.4 - 4.5 데이터베이스 스키마 자동 생성, DDL 생성 기능

Reference. 자바 ORM 표준 JPA 프로그래밍

책 목차 및 이전 글

4.4 데이터베이스 스키마 자동 생성

  • JPA는 데이터베이스 스키마를 자동으로 생성하는 기능을 지원
  • 클래스의 매핑정보를 보면 어떤 컬럼을 사용하는지 확인 가능
  • JPA는 매핑정보데이터베이스 방언(2.5.1절 참고)을 사용해서 스키마 생성
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="jpabook">
        <properties>
            ...
							<property name="hibernate.show_sql" value="true"/>
							<property name="hibernate.hbm2ddl.auto" value="create"/> <!-- 추가 -->
						...
        </properties>
    </persistence-unit>
</persistence>
  • hibernate.hbm2ddl.auto: 애플리케이션 실행 시점에 데이터베이스 테이블을 자동 생성 옵션
  • hibernate.show_sql: 콘솔에 실행되는 테이블 생성 DDL쿼리를 출력해주는 옵션
DDL 콘솔 출력
Hibernate: 
    drop table MEMBER if exists
Hibernate: 
    create table MEMBER (
        ID varchar(255) not null,
				NAME varchar(255),
        age integer,
				roleType varchar(255),
        createdDate timestamp,
				lastModifiedDate timestamp,
        description clob,
        primary key (ID)
    )

실행 결과

  • 기존 테이블을 삭제 후 다시 생성
  • 자동 생성되는 DDL은 데이터베이스 방언에 따라 다름 (varchar → varchar2, integer → number)
  • 스키마 자동 생성 기능이 만든 DDL은 완벽하지 않음 (참고 정도로만 사용)

hibernate.hbm2ddl.auto 속성

옵션설명
create기존 테이블을 삭제하고 새로 생성 DROP + CREATE
create_dropcreate 속성에 추가로 애플리케이션을 종료할 때 DDL 제거 DROP + CREATE + DROP
update테이블-엔티티 매핑정보를 비교해서 변경 사항만 수정
validate테이블-엔티티 매핑정보를 비교해서 차이가 있으면 경고를 남기고 실행하지 않음 이 설정은 ddl을 수정하지 않음
none자동 생성 기능을 사용하지 않으려면 삭제하거나 유효하지 않은 옵션 값으로 지정 none은 유효하지 않은 옵션 값

주의사항

  • 운영 서버에선 create, create-dtop, update처럼 DLL을 수정하는 옵션은 절대 사용X → 실운영 데이터베이스의 테이블이나 컬럼을 삭제할 수 있음
    • 개발 환경 추천 전략
      • 개발 초기 단계: create 또는 update
      • 초기화 상태로 자동화 된 테스트 개발자/CI 환경: create 또는 create-drop
      • 테스트 서버: update 또는 validate
      • 스테이징, 운영 서버: validate 또는 none

참고

  • JPA 2.1 부터 자동 생성 기능을 표준으로 지원
    • update, validate 옵션을 지원하지 않음
    • 지원 옵션: none, create, drop-and-create, drop
  • 이름 매핑 전략 변경하기 (자바 - 데이터베이스)
    • 자바 언어는 관례상 카멜( Camel ) 표기법을 주로 사용 → roleType
    • 데이터베이스는 관례상 언더스코어( _ )를 주로 사용 → role_type
    • 자바-데이터베이스간 매핑 방법
      1. @Column.name을 명시적으로 사용한 매핑
        @Colum(name="role_type") //언더스코어로 구분
        String roleType          //카멜 표기법으로 구분
      1. org.hibernate.cfg.ImprovedNamingStrategy 클래스를 사용한 매핑 → 테이블 명이나 컬럼명이 생략되면 자바의 카멜 표기법을 언더스코어 표기법으로 매핑
        <property name="hibernate.ejb.naming_strategy" 
        		value="org_hibernate_cfg_ImprovedNamingStrategy"/>

4.5 DDL 생성 기능

  • Member 테이블에서 회원 이름이 필수이고, 10자를 초과하지 않는 제약조건이 추가 됌
@Entity
@Table(name="MEMBER")
public class Member {

    @Id
    @Column(name = "ID")
    private String id;

    @Column(name = "NAME", nullable = false, length = 10)
    private String username;
		...
}
  • @Column.nullable 속성 값을 false로 지정하면 DDL에 not null 제약조건이 추가
  • @Column.length 속성 값은 DDL에 문자 크기를 지정
생성된 DDL 결과
create table MEMBER (
    ID varchar(255) not null,
		NAME varchar(10) not null,  --not null추가, varchar(10) 자리수 변경
		...
    primary key (ID)
)
유니크 제약조건 설정 (@Table.uniqueConstraints)
@Entity(name="Member")
@Table(name="MEMBER", uniqueConstraints = 
	{
		@UniqueConstraint(name = "NAME_AGE_UNIQUE", columnNames = {"NAME", "AGE"})
	},
)
public class Member {
		...
}
ALTER TABLE MEMBER
	ADD CONSTRAINT NAME_AGE_UNIQUE UNIQUE (NAME, AGE)

  • 이런 기능들은 DDL을 자동생성할 때만 사용되고 JPA 실행 로직에는 영향을 주지 않음
    • 스키마 자동 생성 기능을 사용하지 않고 직접 DDL로 만들면 사용할 필요 없음
    • 엔티티만 보고도 손쉽게 제약 조건을 파악할 수 있는 장점