Spring Framework - JPA Entity란?
JPA Entity란?
Entity는 Java Persistence API (JPA)에서 사용되는 개념으로, 객체와 관계형 데이터베이스를 매핑하는 데 사용된다.
Entity 클래스는 데이터베이스 테이블과 매핑되며, 테이블의 각 행은 해당 클래스의 인스턴스와 매핑되어 사용된다.
1. Entity의 역할
데이터베이스 테이블과 매핑
Entity 클래스는 @Entity 어노테이션을 사용하여 데이터베이스 테이블과 매핑되는데
이를 통해 데이터베이스 테이블의 열과 Entity 클래스의 필드 간에 매핑을 설정할 수 있다.
데이터베이스 식별자와 매핑
Entity 클래스에서는 @Id 어노테이션을 사용하여 데이터베이스 테이블의 기본 키를 나타내는 필드를 식별할 수 있다.
데이터베이스 연관 관계와 매핑
Entity 클래스에서는 @ManyToOne, @OneToMany, @OneToOne, @ManyToMany 등의 어노테이션을 사용하여
데이터베이스의 연관 관계를 나타낼 수 있다.
이 어노테이션은 즉시로딩(Eager)과 지연로딩(Lazy)이라는 두 가지 fetch 타입 옵션을 가질 수 있는데
타입에 따라 쿼리의 방식 및 타이밍이 달라서 상황에 적절한 전략을 사용하는게 좋다.
데이터베이스 작업 수행
Entity 클래스들은 EntityManager의 관리를 받아 사용되는데, EntityManager는 Entity 객체를 영속성 컨텍스트에 저장하며 Entity 클래스를 사용하여 데이터베이스 쿼리를 작성하고, 데이터베이스 테이블과 상호 작용한다.
비즈니스 로직 구현
도메인 주도 설계에서는 Entity클래스에 비즈니스 로직을 갖춤으로 써 information expert pattern을 지키며 개발할 수 있다. 또는 Service에 모든 비즈니스 로직을 넣어 Entity는 데이터 전달의 역할로만 사용될 수도 있다. 각각의 장단점이 있기 때문에 상황에 맞는 방법을 선택하는 것이 중요하다.
객체 상태 관리
Entity 클래스는 영속성 컨텍스트를 사용하여 객체 상태를 관리한다.
이를 통해 Entity 클래스의 인스턴스를 메모리에서 관리하고, 데이터베이스와의 일관성을 유지할 수 있다.
2. Entity의 여러가지 @어노테이션
@Entity
@Entity어노테이션이 사용된 클래스는 데이터베이스와 1대 1로 매칭되어 관리된다.
또한 application.yml 또는 properties 등의 파일에서 jpa.hibernate.ddl-auto 설정이 create면 기존 테이블을 삭제 후 Entity테이블을 생성하며 update일 경우 테이블 삭제는 되지 않는다.
@Column
@Column이 사용된 Entity클래스의 내부변수는 데이터베이스의 컬럼과 1대 1로 매칭되며, 옵션을 사용하지 않는다면 생략이 가능하다. 이 또한 ddl-auto 설정이 create면 최초 한번 컬럼이 생성되며 update 일 경우 테이블에 없는 컬럼을 추가해준다. 다만, 컬럼의 속성이 변경되었다면, create으로 테이블을 재생성해주는 것이 안전하다.
그리고 name속성을 명시하지 않는다면 Entity클래스의 내부변수명으로 컬럼명이 작성된다.
@Id
@Id이 사용된 내부변수는 테이블에서 PK(primary key)로 지정되며, 이는 유일한 값을 가지게 된다
@GeneratedValue
보통 PK변수랑 같이 사용되는데 PK값은 유일 값을 가져야 하기 때문에 mysql에서는 auto_increment 옵션을 사용하고,
oracle에서는 시퀀스 방식을 사용하여 PK값에 로직을 적용한다.
그래서 mysql의 경우 GenerationType을 IDENTITY로 하며, oracle의 경우 따로 sequence Oracle객체를 생성해두고 해당 객체를 호출할 때마다 +1을 해주는 방식을 사용한다.
@Enumerated
@Enumerated 어노테이션은 java의 enum클래스로 정의된 내부 코드값을 데이터 타입으로 사용하고자 할 때 사용된다.
속성으로 EnumType.ORDINAL, EnumType.STRING이 있는데 ORDINAL은 enum 객체에 정의된 순서가 컬럼의 값으로 사용되고, STRING은 enum 객체의 문자열 자체가 컬럼의 값으로 사용된다.
@ManyToOne, @OneToMany, @JoinColumn
테이블이 다른 테이블을 참조하거나 참조될 때 사용되는 어노테이션이다. 하나가 많은 쪽에 포함외 되냐에 따라 어느
어노테이션을 사용할지 결정되는데, 많은 쪽 클래스 내부에 있을 경우 @ManyToOne, 하나인 쪽일 경우 @OneToMany를 사용한다. 참고로 @ManyToOne 쪽은 테이블에 컬럼이 생성되며 @OneToMany의 경우 참조되는 쪽이기 때문에 컬럼이 생성되지 않는다.
또한 fetch 전략에 따라 FetchType.Eager과 FetchType.Lazy 옵션을 사용할 수 있는데 두 옵션은 쿼리수와 쿼리타이밍이 다르기 때문에 상황에 적절하게 사용해야한다. 자세한 건 나중에 따로 정리 해서 링크를 열어두겠다.
그리고 @JoinColumn에는 참조되는 Entity의 PK값을 적어주면된다.
@CreationTimestamp
@CreationTimeStamp가 적용된 컬럼은 insert쿼리가 발생 할 때 현재 시간 값을 적용해준다.
@UpdateTimestamp
@UpdateTimeStamp가 적용된 컬럼은 update쿼리가 발생 할 때 현재 시간 값을 적용해준다.
이는 마지막 수정시간을 업데이트해주는 부분을 활성화 할 때 편리하다.