글을 쓰는 이유
Member Entity 클래스를 생성할때, inst_dt ( 데이터 삽입 날짜 ), updt_dt ( 데이터 수정 날짜) 와 같은 날짜들은 모든 Entity가 기본적으로 가지고 있는 컬럼입니다.
해당 컬럼들을 하나의 Entity인 BaseEntity 로 선언하고, 그것을 상속받아 사용하도록 하여 공통의 컬럼들을 하나의 클래스에서 관리할 수 있게 할려고 합니다.
또 이 과정에서 알아보다가 EntityListeners가 존재하는 이유와 Persistence Context에 대하여 정리하게 되었습니다.
BaseEntity 구현한 방법
1. Member Entity 입니다.
@Entity
public class Member extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long member_no;
private String member_id;
private String member_password;
private String member_nickname;
private boolean member_from_social;
}
2. BaseEntity 클래스를 생성합니다.
@MappedSuperclass
@EntityListeners(value = {AuditingEntityListener.class})
@Getter
public class BaseEntity {
@CreatedDate
@Column(name = "inst_dt", updatable = false)
private LocalDateTime inst_dt;
@LastModifiedDate
@Column(name = "updt_dt", updatable = false)
private LocalDateTime updt_dt;
}
- @MappedSuperclass
- 해당 어노테이션이 적용된 클래스는 테이블로 생성되지 않습니다.
- 상속하는 하위 클래스들이 BaseEntity의 필드와 매핑된 테이블을 가지게 됩니다
- @EntityListeners(value = {AuditingEntityListener.class})
- BaseEntity의 변화를 감지하고 처리하기 위해 @EntityListeners로 AuditingEntityListener 클래스를 등록합니다.
- JPA에서 Entity 클래스의 변경사항을 감지하고 처리하기 위한 방법을 제공합니다.
- AuditingEntityListener.class는 Entity의 생명주기 이벤트(생성, 수정) 이 발생할때마다 해당 BaseEntity가 동작하게 해줍니다.
- 이벤트 리스너 클래스는 JPA의 Persistence Context를 활용합니다. ( JPA의 Persistence Context란 ? JPA 내부에서 Entity의 객체가 생성/변경되는 것을 알아낼 수 있는 메모리 공간입니다. )
- JPA 에서 Event Listener를 통해 Entity 를 관리하는 이유는, JPA에서는 하나의 Entity 객체를 유지하고, 필요할때 꺼내서 재사용하는데 이떄 변화가 일어나는지 계속해서 확인해주기 위해 Listener를 활용합니다.
- 이를 통해 Entity 객체가 생성되고 변경되면, BaseEntity의 생성일자(inst_dt)와 수정일자(updt_dt)에 맞는 처리를할 수 있습니다.
- @CreatedDate)
- JPA에서 Entity의 생성시간을 기록합니다.
- @LastModifiedDate
- JPA에서 Entity의 업데이트시간을 기록합니다.
3. 서버실행 클래스에 @EnableJpaAuditing 어노테이션 을 추가합니다.
@SpringBootApplication
@EnableJpaAuditing
public class SeminarHubApplication {
public static void main(String[] args) {
SpringApplication.run(SeminarHubApplication.class, args);
}
}
- @EnableJpaAuditing
- 서버시작시 AuditingEntityListener를 활성시키기 위한 설정입니다.
- (마치, React Redux를 사용하는 듯한 느낌입니다.)
Persistence Context가 JPA에서 제공하는 기능들
Persistence Context를 통해서 JPA에서 제공하고 있는 기능들이 있습니다.
- Entity의 상태를 관리합니다.(수정, 생성을 감지한다는 의미입니다.)
- 위에서 설명했듯이 Listener를 통해 Entity의 변화들을 우리에게도 제공하는 어노테이션이 존재했습니다.
- 지연로딩(Lazy Loading)을 지원합니다.
- 지연로딩은 실제로 객체를 호출하기 전에는 실제로 SQL을 실행하지는 않는다는 기능입니다.
- 그 과정에서 Proxy객체를 사용하여 지연로딩을 지원하는데 Persistence Context가 해당 기능을 지원합니다.
- 트랜잭션 관리
- Persistence Context는 Transaction 단위로 동작합니다. 즉, Transaction 내에서 하고자 하는 모든 작업을 실행할경우 데이터베이스에 반영하고, Transaction 내에서 모든 작업들을 실행하지 못할경우 반영하지 않습니다.
- Persistence Context가 Entity를 생성/관리 하기에 제공하는 작업입니다.
- JPA에서는 Transaction을 @Transaction 하나로만 사용해도 바로 사용가능한데, 이것이 그 편리함을 주는 것 같습니다.
그 외에도 1차캐시(First-Level Cache), Dirty Checking 과 같이 더 많은 기능을 제공하는데 위의 것들만 정리하고 넘어가도록 하겠습니다.
정리
BaseEntity가 어떻게 등록시간과 수정시간을 인지하고, Entity 가 변화될때마다 어떻게 해당 값들을 넣어주는지 알게 되었습니다.
특히, JPA의 Persistence Context가 엔티티들을 관리하고, 해당 엔티티들은 새로 생성하고, 삭제하는 것이 아닌 Persistence Context 메모리 구간에 존재하면서 필요할때마다 해당 메모리들에 있는 참조값들을 불러와서 사용하는 것이라고 이해하게 되었습니다.
이러한 이해를 바탕으로 개발할때 사용하게 되는 경험을 겪는다면, 추가적으로 포스팅을 할 수도 있을 것 같습니다.