본문 바로가기
  • 실행력이 모든걸 결정한다
Spring 사전 준비/JPA Hibernate

[JPA] Entity Annotations

by 김코더 김주역 2021. 8. 16.
반응형

※ JPA 어노테이션들은 javax.persistence 패키지에 있다.

 

1. @Entity

1) 설명 : DB랑 매핑하는 클래스

 

2) 속성

- name 속성으로 JPA에서 사용할 엔티티 이름을 지정할 수 있으며, 생략하면 클래스 이름을 사용한다. 다른 패키지에 이름이 같은 엔티티 클래스가 있을 때 충돌을 막기 위해 사용할 수 있다.

 

3) 주의 사항

- 생성자는 필수로 있어야 한다. 자바에서는 생성자를 따로 직접 만들지 않았다면 기본 생성자를 자동으로 만들어준다.

- final, enum, interface, inner 클래스에는 사용할 수 없다.

- 필드에 final을 사용할 수 없다.

 

 

 

2. @Table

1) 설명 : 엔티티 클래스에 매핑할 테이블 정보를 설정

 

2) 속성

(1) name : 매핑할 테이블 이름을 지정할 수 있으며, 생략하면 엔티티 이름을 테이블 이름으로 매핑한다.

(2) catalog : DB의 catalog를 매핑

(3) schema : DB의 schema를 매핑

(4) uniqueConstraints : 스키마 자동 생성 기능을 이용한 DDL 생성 시에 유니크 제약조건을 생성

@Table(name="MEMBER", uniqueConstraints={@UniqueConstraint(name="NAME_PHONE_UNIQUE", columnNames={"NAME", "PHONE"})})
// ALTER TABLE MEMBER ADD CONSTRAINT NAME_PHONE_UNIQUE UNIQUE (NAME, PHONE)

 

 

 

3. @Id

1) 설명 : DB 기본키와 매핑할 필드

 

2) 키 직접 할당

- 애플리케이션에서 기본 키를 직접 할당하는 방법

Member member = new Member();
member.setId(1);

- 식별자 값 없이 저장하면 javax.persistence.PersistenceException 예외가 발생하며, 하위에 org.hibernate.id.IdentifierGenerationException 예외를 포함한다.

 

 

3) 키 자동 할당 전략

- persistence.xml의 <properties>에 다음 프로퍼티를 추가해야 키 생성 전략을 사용할 수 있음

<property name="hibernate.id.new_generator_mappings" value="true" />

- @Id와 @GeneratedValue를 같이 사용 

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) // 키 자동 할당 전략으로는 IDENTITY, SEQUENCE, TABLE이 있다.
private Long id;

 

(1) IDENTITY

- 기본 키 생성을 데이터베이스에 위임하는 전략으로, DB에 값을 저장하면 기본 키 값이 할당됨

- 이 전략을 사용한다면, EntityManager.persist()를 호출했을 때 JPA는 즉시 엔티티를 DB에 저장하고 기본 키 값을 얻어온다. 즉, 쓰기 지연이 동작하지 않는다.

- 주로 MySQL, SQL Server, DB2, PostgreSQL에서 사용됨

 

(2) SEQUENCE

- 유일한 값을 순서대로 생성하는 오브젝트인 시퀀스를 사용하여 기본 키를 할당

- DB에서 시퀀스를 미리 생성해두고, @SequenceGenerator 어노테이션을 이용하여 시퀀스 생성기를 등록한다. 그리고 시퀀스 생성기에 등록한 시퀀스 이름을 @GeneratedValue의 generator 엘리먼트에 지정하면 된다.

CREATE SEQUENCE MEM_SEQ START WITH 1 INCREMENT BY 1;

 

@Entity
@SequenceGenerator(name="MEM_SEQ_GENERATOR", sequenceName="MEM_SEQ", initialValue=1, allocationSize=1) // @GeneratedValue 옆에도 작성 가능
public class Member {
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="MEM_SEQ_GENERATOR")
    private Long id;
    ...
}

※ sequenceName : DB에 등록된 시퀀스 이름 [hibernate 기본값 "hibernate_sequence"]

※ initialValue : 시작하는 수 [기본값 1]

※ allocationSize : 시퀀스 호출 당 증가(할당)하는 수를 의미하며, 성능 최적화용으로 사용된다. [기본값 50]

- 데이터베이스의 시퀀스를 사용하기 때문에 쓰기 지연이 동작한다.

- 주로 Oracle, DB2, H2, PostgreSQL에서 사용됨

 

(3) TABLE

- 다음과 같이 키 생성용 테이블을 하나 만들어두는 방식으로 키 값을 자동으로 생성

CREATE TABLE MY_SEQUENCES (
    SEQUENCE_NAME VARCHAR(255) NOT NULL,
    NEXT_VAL BIGINT, # 시퀀스 값
    PRIMARY KEY (SEQUENCE_NAME)
)

 

@Entity
@TableGenerator(name="MEM_SEQ_GENERATOR", table="MY_SEQUENCES", pkColumnValue="MEM_SEQ", allocationSize=1) // @GeneratedValue 옆에도 작성 가능
public class Member {
    @Id
    @GeneratedValue(strategy=GenerationType.TABLE, generator="MEM_SEQ_GENERATOR")
    private Long id;
    ...
}

 

※ 더 많은 @TableGenerator 속성은 아래 표를 참고하면 된다.

출처 : https://velog.io/@kakdark/%EC%97%94%ED%8B%B0%ED%8B%B0-%EB%A7%A4%ED%95%91

- IDENTITY, SEQUENCE와 달리 모든 데이터베이스에서 사용할 수 있는 전략

 

(4) AUTO

- 기본값

- DB에 따라 자동으로 위 3개의 옵션들 중 하나를 선택

※ MySQL은 IDENTITY를, Oracle은 SEQUENCE를 사용함

 

+추가) 스키마 자동 생성 기능을 사용한다면 하이버네이트는 기본값을 사용해서 적절한 시퀀스나 키 생성용 테이블을 만들어 준다.

 

 

 

4. @GeneratedValue

1) 설명 : @Id와 같이 사용하며, 기본키의 값을 자동 생성하는 방식을 명시

 

2) 속성

(1) strategy : 기본키 자동 생성 전략

(2) generator : @SequenceGenerator, @TableGenerator에 명시된 Generator

 

 

 

5. @Column

1) 설명 : 테이블의 컬럼에 매핑할 필드

 

2) 속성

(1) name : 테이블에서 매핑할 컬럼의 이름. 생략하면 필드의 이름으로 적용

※ 자바 언어의 관례적 표기법(Camel)과 DB의 관례적 표기법(Underscore)이 다르기 때문에, 일일이 명시적으로 name속성을 사용하는 것은 번거로울 수 있다. 이 때는 persistence.xml의 <properties>에 다음과 같이 이름 매핑 전략 속성을 추가하면 된다.

<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />

(2) nullable : null 허용 여부 [기본값 true]

※ 자바 기본 타입의 경우에는 null값을 가질 수 없기 때문에 JPA에서 not null 제약 조건을 자동으로 추가해준다.

(3) unique : 유니크 제약 조건을 걸 때 사용

(4) insertable : Entity 저장 시 Insert 가능 여부 [기본값 true] (false로 설정하면 읽기 전용)

(5) updatable : Entity 수정 시 Update 가능 여부 [기본값 true] (false로 설정하면 읽기 전용)

(6) length : 문자 길이 설정 [기본값 255]

(7) precision : 전체 자리수 [기본값 19] (BigDecimal, BigInteger에서 사용 가능)

(8) scale : 소수점 자리수 [기본값 2] (BigDecimal, BigInteger에서 사용 가능)

(9) columnDefinition : 필드 옵션 직접 지정

@Column(columnDefinition="varchar(50) default 'none'") // 길이 제한, 기본값 설정

(10) table : 지정한 필드를 다른 테이블에 매핑할 때 사용

 

 

 

6. @Enumerated

1) 설명 : enum 타입 필드

 

2) 파라미터

파라미터는 Enumtype.ORDINAL이 기본값으로 되어 있지만, EnumType.STRING으로 설정하는 것을 권장한다. 열거형의 인덱스로 표현하는 것은 위험하기 때문이다.

enum Role { ADMIN, VIP, USER }

 

@Enumerated(EnumType.STRING)
private Role role;

 

 

 

7. @Temporal

1) 설명 : 날짜 필드

※ java.util.Date, java.util.Calendar

 

2) 파라미터

@Temporal(TemporalType.DATE)
private Date date;

@Temporal(TemporalType.TIME)
private Date time;

@Temporal(TemporalType.TIMESTAMP)
private Date timestamp;

(1) TemporalType.DATE : 년-월-일

(2) TemporalType.TIME : 시:분:초

(3) TemporalType.TIMESTAMP : 년-월-일 시:분:초 (기본값)

 

 

 

8. @Lob

설명 : Lob은 Large Object의 줄임말이다. 주로 이미지 정보처럼 많은 자리수를 사용하는 컬럼에 이용하며, CLOB과 BLOB 타입을 매핑한다.

 

1) CLOB

- 필드 타입이 문자일 때 매핑됨

- DB의 lobString 타입과 매핑됨

- 예) String, char[], java.sql.CLOB

 

2) BLOB

- 필드 타입이 문자가 아닐 때 매핑됨

- DB의 lobByte 타입과 매핑됨

- 예) byte[], java.sql.BLOB

 

 

 

9. @Transient

설명 : 실제로 매핑하지 않고 엔티티에만 저장해 둘 필드

 

 

 

10. @Access

1) 설명 : JPA가 엔티티에 접근하는 방식을 지정

 

2) 접근 방식

(1) 필드 직접 접근

- @Id가 필드에 있는 경우에 AccessType.FIELD로 자동 지정됨

 

(2) 프로퍼티 접근

- @Id가 getter 메소드에 있는 경우에 AccessType.PROPERTY로 자동 지정됨

- getter 메소드에서 가공한 값을 반환할 때 사용됨

@Access(AccessType.PROPERTY)
public String getFullName() { return firstName+lastName; }

 

 

 

11. @ManyToOne, @OneToMany

1) 설명 : @ManyToOne은 다대일 매핑에, @OneToMany는 일대다 매핑에 사용된다.

 

2) 속성

(1) optional : 연관된 엔티티가 없어도 되는지에 대한 여부 [기본값 true]

(2) fetch : 글로벌 페치 전략 [@ManyToOne 기본값 FetchType.EAGER, @OneToMany 기본값 FetchType.LAZY]

(3) cascade : 영속성 전이 기능 사용

(4) targetEntity : 연관된 엔티티의 타입 정보를 알 수 없는 경우에 설정

 

3) @JoinColumn

- @ManyToOne 또는 @OneToMany를 통해서 외래 키를 매핑할 때 같이 사용한다.

- name 속성으로 매핑할 외래 키의 이름을 직접 지정할 수 있다. [기본값 필드명+_+참조테이블의 기본 키 컬럼명]

- referencedColumnName 속성으로 외래 키가 참조하는 테이블의 컬럼명을 직접 지정할 수 있다.

- foreignKey 속성으로 외래 키 제약 조건을 직접 생성할 수 있다.

- @Column과 동일하게 unique, nullable, insertable, updatable, columnDefinition, table 속성을 사용할 수 있다.

 

4) 예제

https://kimcoder.tistory.com/358?category=964983

 

[JPA] 단방향 매핑 / 양방향 매핑

테이블 환경에서는 JOIN문을 이용하여 두 테이블간의 양방향 매핑이 가능하지만, 객체 환경에서라면 말이 달라진다. 그렇다면 객체에서는 어떻게 단방향/양방향 매핑을 구현할 수 있는지 알아보

kimcoder.tistory.com

 

 

반응형

댓글