본문 바로가기
BE/JPA

@Column(nullable = false) 와 @NotNull 중 무엇을 사용해야 할까?

by cjsrhd94 2022. 7. 18.

개인 프로젝트 도중 Entity에 DB 제약조건을 적용하다가 궁금점이 생겼다.

 

@Column(nullable = false)

// User.java

@Entity
@Table(name = "user_table")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
public class User extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false)
    @Email
    private String email;

    @Column(nullable = false)
    private String password;

    @Column(unique = true, nullable = false)
    private String nickname;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private Role role;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private Status status;
 
    // Project code...
 
}

JPA에서 일반적으로 특정 컬럼에 null 값이 들어오는 것을 막기 위해 @Column(nullable = false) 옵션을 사용해 컬럼 제약 조건을 설정한다. 위와 같이 Entity를 작성하고 spring.jpa.hibernate.ddl-auto = create 옵션으로 서버를 실행해주면 아래와 같은 쿼리가 발생하며 테이블이 생성된다.

예상대로 @Column(nullable = false) 옵션을 사용한 컬럼에 not null 제약이 붙어있는 것을 확인할 수 있다.

위와 같이 @Column(nullable = false) 옵션이 사용된 컬럼에 null 값을 insert하려고 하면, insert 쿼리가 발생하고  ConstraintViolationException이 발생하며 제약 조건 위반을 알려준다.

 

@NotNull

// User.java

@Entity
@Table(name = "user_table")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
public class User extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    @Email
    @NotNull
    private String email;

    @NotNull
    private String password;

    @NotNull
    private String nickname;

    @Enumerated(EnumType.STRING)
    @NotNull
    private Role role;

    @Enumerated(EnumType.STRING)
    @NotNull
    private Status status;
 
    // Project code...
 
}

그렇다면 validation으로 사용되는 @NotNull도 같은 결과가 나올지 궁금증이 생겨 실험해 보았다. 나는 DB에 not null 제약은 생기지 않고, 유효성 검증 단계에서 Exception이 발생할 것이라고 생각하였다.

그러나 예상과는 다르게 @NotNull 어노테이션을 사용한 컬럼에 not null 제약이 붙어있었다.

@NotNull 옵션이 사용된 컬럼에 null 값을 insert하려고 하면, 유효성 검증 단계에서 ConstraintViolationException이 발생하며 에러 메세지를 발생시켰다. validation 단계에서 Exception이 발생하였기 때문에 쿼리가 발생하지는 않았다.

 

결론

@Column(nullable = false)은 컬럼 제약 조건만 설정해주는 반면, @NotNull은 컬럼 제약 조건 설정에 유효성 검사까지 해주기 때문에 @NotNull이 상위 호환이라고 할 수 있다. 팀 내부 협의를 통해 '@NotNull을 사용하는 것도 괜찮다' 고 생각한다.

댓글