[spring] JPA

이 글은 “스프링부트와 AWS로 혼자 구현한 웹서비스 – 이동욱(조졸두)”를 공부하면서 쓴 글이니 생략된 내용은 구해서 복습하는 것을 추천한다.

참조 소스 코드 github https://github.com/jojoldu/freeelec-springboot2-webservice

http://www.yes24.com/Product/Goods/83849117

Spring Boot와 AWS만으로 웹 서비스 구현 – YES24

웹서비스의 모든 과정을 가장 빠르고 쉽게 경험해보세요. 제목에서 알 수 있듯이 이 책은 Spring Boot와 AWS를 사용하여 웹 서비스를 구현합니다.

JPA 및 JUnit 테스트, Gradle, Mustech 및 Spring

www.yes24.com

책 3장에 해당하는 내용 중 PA Auditing으로 생성시점/변경시점의 자동화를 구성하고자 합니다.

JPA 시험

일반적으로 엔터티에는 데이터 생성 시간과 수정 시간이 포함됩니다.

작성 시기와 수정 시기는 유지 관리에서 중요한 요소입니다.

데이터를 등록하거나 변경할 때마다 날짜 데이터를 등록하거나 변경해야 하는데, 이를 모든 테이블과 서비스 방식에 포함시키면 중복 코드가 많아져 지저분해질 수 있다.

이 문제를 해결하기 위해 JPA 감사를 사용합니다.

LocalDate 사용

– Java 8 LocalDate 및 LocalDateTime이 등장한 이후로,

이는 Java의 기본 날짜 유형인 날짜의 문제입니다.

1. 불변 객체가 아닙니다.

(다중 스레드 환경에서 발생할 수 있는 문제)

2. 달력의 월 값 디자인이 잘못되었습니다.

예: Calendar.OCTOBER의 숫자 값은 10이 아니라 9입니다.

위 두가지를 수정해서 나온 타입입니다.

JPA Auditing으로 생성/수정 시간 자동화

BaseTimeEntity 생성 (com.project.webservic.domain에 있음)

@Getter
//JPA Entity 클래스들이 BaseTimeEntity 클래스를 상속할 경우 이 클래스의 필드들도 칼럼으로 인식하도록 한다.

@MappedSuperclass //BaseTimeEntity 클래스에 Auditing 기능을 포함시킨다.

@EntityListeners(AuditingEntityListener.class) public class BaseTimeEntity { //Entity 생성되어 저장된 시간 자동 저장 @CreatedDate private LocalDateTime createdDate; //조회한 Entity 값 변경시 시간 자동 저장 @LastModifiedDate private LocalDateTime modifiedDate; }

BaseTimeEntity 클래스는 엔티티의 createdDate 및 ModifiedDate를 자동으로 관리합니다.

– @MappedSuperclass: JPA 엔티티 클래스가 BaseTimeEntity를 상속하면 해당 클래스의 필드도 열로 인식됩니다.

– @EntityListeners(AuditingEntityListeners.class): BaseTimeEntity 클래스에 감사 기능을 넣습니다.

– @createdDate: 엔티티가 생성되었을 때 저장된 시간을 자동으로 저장

– @LastModifiedDate: 조회 중인 엔터티 값이 수정되는 시간을 자동으로 저장

Application.java에서 JPA 감사를 활성화하는 주석 추가

//JPA Auditing 활성화
@EnableJpaAuditing
//@SpringBootApplication이 있는 위치부터 설정을 읽음 -> Application 클래스는 프로젝트 최상단에 위치해야 함
@SpringBootApplication
public class Application {
    public static void main(String() args){
        SpringApplication.run(Application.class, args);
    }
}

JPA 감사 테스트 작성

PostsRepositoryTest에 테스트 메서드 추가

@Test
public void BaseTimeEntity_등록() {
    //given
    LocalDateTime now = LocalDateTime.of(2023,2,23,0,0,0);
    postsRepository.save(Posts.builder()
            .title("title")
            .content("content")
            .author("author")
            .build());
    //when
    List<Posts> postsList = postsRepository.findAll();

    //then
    Posts posts = postsList.get(0);

    System.out.println(">>>>>>> createDate="+posts.getCreatedDate()+"   modifiedDate="+posts.getModifiedDate());
    assertThat(posts.getCreatedDate()).isAfter(now);
    assertThat(posts.getModifiedDate()).isAfter(now);
}

테스트 결과 성공


테스트를 통과하고 콘솔을 보면 삽입 시 생성/수정 시간이 컬럼으로 인식되어 저장되고 현재 시간이 저장되는 것을 확인할 수 있습니다.