개인 프로젝트 도중 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을 사용하는 것도 괜찮다' 고 생각한다.
'BE > JPA' 카테고리의 다른 글
JPA에서 soft delete 처리하기 (@Where, @Filter) (0) | 2023.02.01 |
---|---|
스프링 테스트 에러: JPA metamodel must not be empty! (0) | 2022.02.21 |
댓글