ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA Auditing과 MappedSuperClass 활용
    Back-End/JPA 2022. 9. 14. 15:03
    728x90

    프로젝트에서 리뷰, 리뷰 답변 등의 Entity를 설계할 때 성일자와 수정일자 등의 필드가 공통적으로 들어가게 되었다.

     

    또한 이러한 값들의 경우 매번 insert 및 update 시 값을 설정 해 주어야 한다.

     

    이 때, JPA의 Auditing 기능과 MappedSuperClass 기능을 활용하면 이를 간단히 해결할 수 있다.

     

    공식문서를 보면, JPA Auditing은 다음과 같이 정의되어 있다.

     

    In the context of ORM, database auditing means tracking and logging events related to persistent entities

     

     

    현재 프로젝트에서는 생성 시간과 수정 시간만이 필요하므로 이를 Spring JPA Data의 @CreatedAt, @LastModifiedDate 어노테이션만 활용해서 사용 해 볼 것이다.

     

    @Getter
    @MappedSuperclass
    @EntityListeners(AuditingEntityListener.class)
    public abstract class BaseTimeEntity {
    	@CreatedDate
    	private LocalDateTime createdAt;
    
    	@LastModifiedDate
    	private LocalDateTime modifiedAt;
    }

     

    @MappedSuperClass

     

    • 해당 어노테이션이 선언된 클래스는 entity가 아닌, 자식 클래스에 매핑 정보만 제공하는 클래스임을 의미한다.
    • 여러 엔티티에서 사용되는 공통 필드들을 추상화 하여 제공하는 클래스로 생각하면 된다.

     

    @EntityListeners

     

    • hibernate 문서에 따르면, JPA entity에 이벤트가 발생할 때(JPA 라이프 싸이클) 콜백을 처리하는 어노테이션이라고 한다.
    • AuditingEntityListener 클래스는 Spring data JPA에서 제공하는 메서드이다. 해당 기능을 통해 CreatedDate, LastModifiedDate 어노테이션을 탐색하여 persist 시 해당 필드값을 자동으로 업데이트 해 준다.
    • 해당 클래스를 value로 추가함으로써 콜백 처리가 가능 해 진다.
    @Entity
    @Getter
    @Builder(builderMethodName = "ReviewBuilder")
    @NoArgsConstructor(access = AccessLevel.PROTECTED)
    @AllArgsConstructor
    public class Review extends BaseTimeEntity {
    	@Id
    	@GeneratedValue(generator = "UUID")
    	@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    	@Column(name = "REVIEW_ID", columnDefinition = "BINARY(16)")
    	private UUID id;
    
    	@ManyToOne(fetch = FetchType.LAZY)
    	@JoinColumn(foreignKey = @ForeignKey(name = "FK_review_item_id"), name = "item_id", nullable = false)
    	private Item item;
    
    	@Column(nullable = false)
    	private String title;
    
    	@Column(nullable = false)
    	private String content;
    
    	@ManyToOne(fetch = FetchType.LAZY)
    	@JoinColumn(name = "USER_ID")
    	private User user;
    
    	@OneToMany(mappedBy = "review", cascade = CascadeType.ALL, orphanRemoval = true)
    	@Builder.Default
    	private List<ReviewImage> reviewImages = new ArrayList<>();
    }

     

    다음과 같이, Review Entity에 필요한 필드들을 넣고, BaseTimeEntiy를 상속한 뒤 application을 실행한다.

     

    jpa의 ddl-auto에 create-drop 옵션을 준 뒤, 터미널을 통해 테이블 구조를 살펴보면

     

     

    다음과 같이 datetime 타입으로 해당하는 컬럼들이 잘 추가되었음을 알 수 있다.

     

     

     

     

    Reference

    https://wave1994.tistory.com/161

     

     

    댓글

Designed by Tistory.