[JPA] Entity 기본값 지정
date
‣
slug
jpa-how-to-set-default
status
Published
tags
summary
type
Post
들어가며
JPA Entity를 작성할 때, 필드의 기본값을 지정해주고 싶을 때가 있다. 이 글에서는 엔티티의 기본 값을 지정하는 몇 가지 방법과, 주의점에 대해 살펴보려한다.
1. columnDefinition을 이용해 DDL로 기본 값 지정하기
JPA의 @Column 어노테이션에는,
columnDefinition 옵션을 사용할 수 있다.columnDefinition 옵션을 설정하게 되면, JPA에서 ddl-auto로 테이블을 생성할 때, DDL을 다음과 같이 작성한다.
name VARCHAR(255) DEFAULT 'anonymous'와 같이, DDL 자체에 기본값이 지정된 것을 볼 수 있다. 그렇다면 객체를 생성했을 때, 기본값이 지정되는지 확인해보자.[테스트 코드]
new 키워드로 새로운 객체를 생성한 뒤, 두 번의 출력을 해주었다. (생성 직후 / findBy로 조회)
[결과]

예상과는 다르게 이름에 null 값이 들어있다. DML을 살펴보면, 애초에 null 값이 바인딩되어있는 것을 확인할 수 있다.
이처럼 기본값을 지정했는데도 불구하고 DB에 null이 삽입되는 이유는, coulmnDefinition 옵션은 DDL의 기본값을 설정하는 옵션이지 엔티티의 기본값을 설정하는 옵션이 아니기 때문이다.
즉, 우리는 DDL의 기본값은 'anonymous' 로 설정해놓았지만, null 이 담긴 엔티티를 생성, 저장하였으므로 의도적으로 null 값을 삽입한 것이나 마찬가지이다.
[해결법 1: @DynamicInsert]
이를 해결하고 싶다면, 엔티티 클래스 위에 @DynamicInsert 어노테이션을 추가해주면된다. 이 어노테이션을 추가하게되면, Jpa는 쿼리문을 날릴 때 null 인 값은 제외하고 쿼리문을 작성한다.
아래는 @DynamicInsert 어노테이션만 추가하여 같은 코드를 실행한 결과이다.

null 값인 name을 제외하고 삽입 쿼리가 작성된 것을 확인할 수 있다. 한 가지 주의점은, DB 삽입 직후에는 엔티티의 값이 갱신되지 않는다.
즉, 삽입 직후 기본값을 가져와 사용하고 싶다면 조회를 통해 엔티티의 값을 갱신해주어야한다.
추가로 업데이트 시에도 null 값을 확인해주는
@DynamicUpdate 어노테이션도 존재하니 필요 시 활용하자.[해결법 2: 필드에 기본값 지정]
@DymamicInsert의 경우 null 값에 대한 insert를 제외시키지만, primitive type의 경우 기본값을 가져버리므로 문제가 발생한다.
예를 들어 boolean 타입의 경우, 기본값으로 false를 가지기 때문에 DEFAULT TRUE와 같이 기본값을 지정하여도 false가 항상 삽입되게된다. 이 경우에는 필드 또는 생성자에 직접 기본값을 지정해 줄 수 있다.
2. @ColumnDefalut 어노테이션 사용하기
@ColumDefault 어노테이션은 동작 방식 자체는 1번의 columnDefinition 옵션과 동일하다.
즉, 아래의 두 코드는 같은 동작을 수행한다.
구체적인 동작방식이나 주의점은 1번에서 설명하였으므로 생략하겠다. 다만, "'anonymous'" 와 같이 문자열을 기본값으로 지정할 때에는, 작은 따옴표로 한 번 더 감싸주어야 DDL이 제대로 작성된다.
3. @Builder를 사용한다면 @Builder.Default
빌더 패턴은 여러 곳에서 사용되는데, 특히 많은 필드를 가진 엔티티를 생성할 때 유용하다. 우리는 그 중에서도 Lombok의 @Builder 를 사용하게 되는데, 여기에는 한 가지 문제가 있다.
Lombok의
@Builder는 내부적으로 별도의 빌더 클래스를 생성하는데, 이 빌더 클래스는 원래 클래스의 필드 초기화를 무시하고, 빌더를 통해 제공된 값만 사용하여 객체를 생성하게된다. 따라서 우리가 기존에 사용하던 방식대로 기본 값을 지정하면 똑같이 null이 삽입되는 문제를 겪을 수 있다.
따라서
@Builder를 사용하여 엔티티를 주로 생성하는 경우에는, 기본 값 지정이 필요한 필드 위에 @Builder.Default 어노테이션을 붙여 빌터 패턴 사용 시에도 기본 값이 지정될 수 있도록 해줘야한다.