@ColumnDefault+@DynamicInsert vs @PrePersist

이진규·2023년 3월 29일
0

SPRING 지식 공유

목록 보기
6/17

@ColumnDefault+@DynamicInsert vs @PrePersist

필요로 하는 기능은 다음과 같았다.

게시판 작성시 DTO로 넘어오는 null값인 조회 수, 추천 수, 댓글 수는 0으로 초기화 될 수 있도록 한다.

그래서 자연스럽게 Entity에 조회 수, 추천 수, 댓글 수에 해당하는 컬럼 위에 @ColumnDefault("0")과 같이 작성하고 테스트를 해보았지만 실패했다. 이유를 찾던 중 @PrePersist를 이용하여 0으로 초기화 하는데 성공하였고 왜 @ColumnDefault으로는 성공하지 못했는지와 @PrePersist에 대해 기술해보겠다!

결론적으로는, 내가 @ColumnDefault의 역할을 완전히 오해하고 있었다.

@ColumnDefault를 쓰면, @RequestBody로 받은 DTO에서 해당 컬럼의 값이 들어오지 않아 null로 되었을 때 그 값이 어노테이션에 설정해둔 default 값으로 바뀌는 줄 알았다. 그리고 그 상태로 DB에 save하는 줄 알았다.

그런데 그게 아니라, application.yml에서 jpa.hibernate.ddl-auto : create-drop 로 설정하고 서버를 구동시켰을 때 생성된 DDL을 보면 그때 default가 적용되어 있는 걸 확인할 수 있다. 즉, 저 어노테이션은 auto-ddl을 사용할 때에 적용되는 것이다.

@DynamicInsert는 insert시 null값인 필드를 쿼리문에서 제거해준다.
즉, @DynamicInsert를 추가로 정의해줌으로써 아예 null값이 되었을 때 쿼리문에서 제외되도록 해야, DDL에 설정한 @ColumnDefault값이 제대로 잘 들어가진다.

다른 방법으로는 @PrePersist가 있다.

persist() 메서드를 호출해서 엔티티를 영속성컨텍스트에 관리하기 직전에 호출 된다. 식별자 생성 전략을 사용한 경우 엔티티에 식별자는 아직 존재 하지 않는다. 새로운 인스턴스를 merge할 때도 수행된다.

다음과 같이 Entity에 @PrePersist를 정의해줌으로써 null값인 경우 0으로 초기화 할 수 있도록 설정할 수 있다.

    @PrePersist
    public void prePersist() {
        this.viewCnt = this.viewCnt == null ? 0 : this.viewCnt;
        this.recommendCnt = this.recommendCnt == null ? 0 : this.recommendCnt;
    }

참고자료

@ColumnDefault와 @DynamicInsert 관련 자료

profile
항상 궁금해하고 공부하고 기록하자.

0개의 댓글