JPA - @NotNull vs @Column(nullable = false)
@NotNull과 @Column(nullable=false) 의 차이가 뭘까?
엔티티 필드에 선언하게 되면, 두 어노테이션 모두 동일한 결과를 보이는 듯 하다.
둘 모두 DB 테이블 생성시, 해당하는 칼럼에 not null 제약 조건이 생긴다.
그렇다면 차이점이 무엇일까?
1. 종속성이 다르다(위치한 라이브러리가 다르다.)
@Column 은 JPA에서 기본 제공하는 어노테이션이므로, 별다른 종속성을 추가할 필요가 없다.
그러나 @NotNull 어노테이션은 BeanValidation API에서 제공하므로, @NotNull을 추가하려면 빌드 도구에 종속성을 추가해야한다.
//build.gradle의 경우
implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
//spring-boot를 사용한다면 위 대신 이걸 추가하자
implementation 'org.springframework.boot:spring-boot-starter-validation'
2. 체크하는 시스템이 다르다.
@Column(nullable = false) 는 DB 테이블 생성시에 not null 제약조건을 추가할 뿐이다.
해당 칼럼에 null이 할당된 채로 DB에 저장하려고 하더라도, Java Application에서는 검사하지 않는다.
SQL문이 실행되면서 not null 제약 조건에 걸려 실패할 뿐이다.
@NotNull 은 테이블 생성시에 not null 제약조건을 추가할 뿐 아니라,
해당 엔티티를 DB에 저장하려고 할 경우 Java application에서 해당 필드가 null인지 검사하게 된다.
즉 JPA의 life-cycle중 pre-persist나 pre-update 시점에서 해당 필드가 null인지 검사하게 된다.
@Column(nullable = false)은 DB에서 null인지 체크하게 되고,
@NotNull은 java application에서 null인지 체크하게 된다.
3. 체크하는 시점이 다르다.
위에서 설명한 바와 같다.
@Column(nullable = false)는 SQL문이 실행되는 시점에 not null 제약조건을 통해 체크하게 된다.
(해당 어노테이션은 단순히 테이블 생성시 제약조건을 만들어줄 뿐이다.)
반면, @NotNull은 pre-persist 또는 pre-update 시점에 null인지 체크하게 된다.
어떤 걸 사용하는게 좋을까?
내가 참고한 글의 글쓴이는 @NotNull을 사용하길 추천한다.
당연한 것이, 잘못된 SQL이 실행되기 전에 java application 단에서 체크할 수 있기 때문이다.
Database constraints are an important tool to ensure data consistency, but you shouldn’t rely on them in your Java application.