필요로 하는 기능은 다음과 같았다.
게시판 작성시 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;
}