순수 JPA로 하는 법
@MappedSuperclass를 선언한 속성값 선언용 Class를 만들어 Entity에서 상속받게 하라.
- MappedSuperclass 생성, 변수 선언
@MappedSuperclass //실제 상속관계는 아니고 그냥 값만 내려서 사용할 수 있게 해주는 class
//이걸 선언해야 이후 상속한 Entity Table 생성시 변수값이 추가된다.
public class JpaBaseEntity {
@Column(updatable = false) //DB의 값이 변경되지 않게 고정해주는 어노테이션
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
@PrePersist //persist (등록) 하기전에 발동
public void prePersist(){
LocalDateTime now = LocalDateTime.now();
createdDate = now;
updatedDate = now;
}
@PreUpdate //update 전에 발동
public void preUpdate(){
updatedDate = LocalDateTime.now();
}
}
@MappedSuperclass
실제 Entity에서 상속하여 사용하지만, 그냥 변수 값만 내려 사용할 수 잇게 해주는 class이다.
이걸 선언해야 이후 상속한 Entity Table 생성시 변수값이 추가된다.
@Column(updatable = false)
본문에서는 createdDate가 최초 create시에만 들어가고 불변의 값이라 선언해줬다.@PrePersist,PreUpdateEntity의 Update, Create 사전에 작동하는 메서드에 선언한다.
- 생성일자가 등록되길 원하는 Entity에 상속
public class Member **extends JpaBaseEntity**{
}
- 테스트
created_date, updated_date가 추가되어 생성되는 모습
create table member (
member_id bigint not null,
created_date timestamp,
updated_date timestamp,
age integer not null,
username varchar(255),
team_id bigint,
primary key (member_id)
)
@Test
public void mappedSuperClassTest() throws Exception {
//given
Member m1 = new Member("user1");
memberRepository.save(m1); //@PrePersist 작동
Thread.sleep(100);
m1.setUsername("user2222");
//when
em.flush();
em.clear();
Member member = memberRepository.findById(m1.getId()).get();
//then
Assertions.assertThat(m1.getUpdatedDate()).isNotEqualTo(member.getUpdatedDate());
}
SpringDataJpa
@EnableJpaAuditing을 선언해서 Jpa의 Auditing 기능을 사용한다고 명시하고, auditorProvidor 메서드를 함께 명시해줘서
사용자, 수정자 등록시 가져갈 내용을 정의해준다.
이후 원하는공통 속성을 구분해서 class별로 선언해서 필요한 Entity에서 상속 받는다. (주로 시간과 나머지를 나눔)
Application에@EnableJpaAuditing선언
@EnableJpaAuditingJpa의 Auditing 기능을 사용한다고 명시함.
@SpringBootApplication
**@EnableJpaAuditing** //JpaAuditing 기능을 사용한다고 명시함.
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
// 생성자, 수정자 등록시에 필요하다. JPA Auditing에서 고유 유저값 가져감
@Bean
public AuditorAware<String> **autitorProvidor()**{
//보통 Spring Security나 Session 등을 가져와 고유값을 넣어준다.
return () -> Optional.of(UUID.randomUUID().toString());
}
}
공통 속성정의한 Class에@EntityListeners,@MappedSuperclass,@CreatedBy,@LastModifiedBy선언
@EntityListeners(AuditingEntityListener.class)이벤트를 기반으로 동작한다고 선언하는 것.@MappedSuperclass공통속성용을 위해 상속용 class 선언@CreatedBy생성자 (Application.class에 선언된 auditorProvider에서 사용자 정보 가져가서 대입해준다.)@LastModifiedBy이하 동문
@EntityListeners(AuditingEntityListener.class) //이벤트를 기반으로 동작한다고 선언하는 것
@MappedSuperclass
@Getter
public class BaseEntity {
//생성자, 수정자
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
실무 팁
공통 속셩별로 빼서 여러 class로 분산해서 필요에 따라 Entity에서 상속받아 적용하게 만든다.
너무 간단한 것들은 그냥 Entity 내부에 선언해주어도 무방하다.
- Time속성 정의된 Class
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseTimeEntity {
@CreatedDate //org.springframework.data.annotation 데이터쪽 annotation이다.
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
- 생성자,수정자 속성 정의된 Class
@EntityListeners(AuditingEntityListener.class) //이벤트를 기반으로 동작한다고 선언하는 것
@MappedSuperclass
@Getter
public class BaseEntity {
//생성자, 수정자
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
'스프링 > JPA' 카테고리의 다른 글
| [JPA 기초] 기본 Entity 설정시 사용되는 annotation 정리 (0) | 2022.04.05 |
|---|---|
| Query By Example 간단 예제, 사용 (0) | 2022.03.01 |
| `SpringDataJPA` 기본 save 작동 과정 (merge와 persist를 중심으로 효율성 개선) (0) | 2022.02.27 |
| API 구현시 Parameter로 자동 Paging 객체 매핑하기 (0) | 2022.02.25 |
| Spring Data JPA 구현체를 만들고 싶다면? (0) | 2022.02.23 |