| 정리하게 된 계기
- 오늘 수업에서는 계좌 관련 프로그램을 만드는 걸 시작했고,
계좌 생성 API를 만들며, 사용자 및 계좌에 대한 Entity를 만들었었다.
- 만들다보니, @Entity, @EntityListeners, @id, @Generated의 상위 패키지가 persistence로 되어 있는게 보였다.
- 더불어, 객체 이벤트 발생 시간을 알려주는 @EntityListeners(AuditingEntityListener.class) 코드의
AuditingEntityListener.class로 가, 설명을 읽어보니,
"이건 Entity에 persist 또는 update 이벤트가 발생하는 시간을 알려주는 일회성(stateless) 클래스이다"
라고 적혀있어, persist가 뭐지? 하는 생각을 하게 됐다.
| JPA에서 말하는 영속성이란
- JPA는 풀어서 Java Persistence API라고 했다.
- 앞서서는 위의 persistence란 자바 코드를 유지하는 것을 말한다고 했는데,
사실 * persist()란, "영구적으로 DB에 반영하다"를 의미한다.
그러나 JPA는 정확히 자바를 통해 DB에 영구적으로 반영하는 API라는 의미였다.
- 우리가 JPA를 통해 어떤 테이블, 다른 말로 Entity를 만들고자 하면, 아래와 같은 단계를 거칠 수 있다.
비영속(new) | 영속(managed) | 준영속(detached) | 삭제(removed) | |
메소드 | new | persist() | detach() - 특정 entity 분리 | remove() |
특징 | 자바 Object 생성 | DB에 반영 | 엔터티 매니저 관리X | 삭제 |
persistence context에 Entity포함 |
X | O | X | X |
- 영속성 컨텍스트(persistence context)는 실제하진 않고 논리적인 개념으로, 엔터티를 영구 저장하는 환경을 말한다.
- 우리는 자바를 통해 객체를 만들고 이를 DB에 반영할 것을 JPA api에게 요청한다.
요청이 DB에 반영이 되는 순간이 곧, persist()되는 순간이다.
- 그러면, 다시 Entity를 만드는 자바 코드로 돌아가서 생각을 해보겠다.
package com.example.animal.domain;
import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.time.LocalDateTime;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@EntityListener(AuditingEntityListener.class)
public class Patient{
@Id
@GeneratedValue
private Long id;
private String name;
private String kind;
private String sex;
@OneToMany
@JoinColumn(name = "PatientOwner_id")
private PatientOwner patientOwner;
@CreatedDate
private LocateDate createdAt;
@LastModifiedDate
private LocateDate updatedAt;
}
- 앞에서 만들었던 동물병원 진료 예약 시스템에서, 동물을 Patient로 해서 만들어봤다.
간단한 내역만 적어두었는데, Entity에 관한 Annotation import를 보면 persistence가 패키지명으로 들어간 게 보인다.
- 다시 말해 @Entity 표시만 해두고, @Id나 @GeneratedValue로 pk를 설정하면 알아서 DB에 영구 반영시키겠단 말이다.
- 그리고 @EntityListener는 이 과정에서 발생하는 이벤트 상황을 원하는 바에 따라 읽어오겠다는 이야기이다.
- 그런데 잠시 고민해야 하는 부분이 더 있다.
- @EntityListener를 저렇게 표시만 해둔다고 쓸 수는 없단다.
Listener는 말 그대로 이벤트가 발생할 때까지 귀기울여 대기하는 녀석이기에,
대기할 수 있게 미리 DI Container에 넣어주어야 한다.
| AuditingEntityConfig 클래스를 만들기
- 우리는 EntityListener중에서도 AuditingEntityListener를 쓰려고 한다.
- 그리고 앞서서 스프링은 처음에 프로그램을 시작할 때, DI container안에 의존성을 주입한다고 했으며,
- 리스너는 미리 이 container안에 넣어서 대기시켜주어야한다고 했다.
* DI container에 의존성을 주입하려면 @Configuration을 붙인 설정 클래스 안에서 @Bean을 불려오는 것으로 할 수 있는데
이 밖에도 @Component 등이 @Bean을 상속하여 붙이는 순간 시작 시 자동으로 의존성이 주입되기도 했다.
- 리스너를 대기시키기 위해 Config 클래스를 하나 만들고 @Configuration과 @EnableJpaAuditing을 붙인다.
@Configuration
@EnableJpaAuditing
public class JpaAuditingConfig {
}
| 정리
- JPA에서 말하는 영속성이란, DB에 영구적으로 반영되었음을 의미한다. - @Entity, @EntityListener, @Id, @GeneratedValue 에는 이러한 영속성의 의미가 패키지명에 담겨 있다. - @EntityListener(AuditingEntityListener.class)는 Entity에 create/update 이벤트가 발생하는 시간을 알려준다. - Entity 내부의 맴버에 @CreatedDate와 @LastModifiedDate를 추가하고, - JpaAuditingConfig 클래스를 만든 후 @Configuration과 @EnableJpaAuditing을 추가하여 사용한다. |
[ 참조 및 출처 ]
부트캠프 수업 후 정리
JPA persistence context https://victorydntmd.tistory.com/207
Entity Listeners https://wave1994.tistory.com/161
'Framework > Spring' 카테고리의 다른 글
[HTTP] User IP와 Agent(Device) 정보 가져오기 (0) | 2022.10.15 |
---|---|
[Validation] 데이터 검증, 비즈니스 로직 검증 (1) | 2022.09.21 |
[스프링] 개발을 시작하기 전에 - 요구 사항 분석, 기본 구조 잡기 (1) | 2022.09.15 |
[스프링] 프로젝트 전 꼭 알아두면 좋은 것들 (0) | 2022.09.13 |
[스프링] 스프링 MVC - 예외처리 (1) | 2022.09.11 |