목표: JPA를 통해 엔티티를 save 할 때, 특정 필드에 따로 값을 넣지 않아도 default value가 저장되도록 설정하자.
타겟 컬럼: usage_status → 해당 데이터에 대한 사용 여부 (YES or NO)
@ColumnDefault
<User 엔티티>
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id", nullable = false)\
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
@ColumnDefault("'YES'") // default
@Enumerated(EnumType.STRING)
private UsageStatus usageStatus;
}
@ColumnDefault는 ddl-auto 옵션으로 DDL을 생성할 때 자동으로 default 제약사항을 넣어주는 애노테이션이다.
실제로 생성된 DDL은 다음과 같다.
create table users (
user_id bigserial not null,
usage_status varchar(255) default 'YES' not null,
name varchar(255) not null,
primary key (user_id)
)
usage_status 컬럼에 default 'YES'가 추가된 것을 볼 수 있다.
이제 따로 UsageStatus 필드에 값을 넣지 않아도 User를 save할 수 있을 것으로 예상된다.
User user = User.builder()
.name(name)
.build();
em.persist(user);
그러나 아래와 같은 예외가 발생한다.
Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "usage_staus
요약하자면 usage_status 컬럼에 Not Null 제약사항이 걸려있는데, null 값을 저장하려 했다는 것이다.
분명 @ColumnDefault로 deafult value를 세팅해줬는데 이상하다.
실제 날라간 쿼리를 보자.
insert into users (usage_status, name) values (NULL, 'han1');
usage_status에 NULL이 저장된다.
이 부분에서 usage_status 컬럼의 Not Null 제약사항과 실제 NULL 값이 들어가는 과정에서 예외가 발생한 것 같다.
@ColumnDeafult에 관해 공식 문서를 찾아보니,
사실 @ColumnDeafult는 default 제약사항을 넣어주는 것 뿐이지, null인 값을 default value로 바꿔주지 않는다.
→ 애초에 insert 할 때, usage_status 값을 주지 않아야 DB에서 자동으로 default value로 설정하는 프로세스였다.
@DynamicInsert
그렇다면 null인 값은 자동으로 insert 쿼리에 포함되지 않게 세팅해보자.
@DynamicInsert 애노테이션은 엔티티를 save할 때 null 값은 배제하고 insert 쿼리를 날리도록 한다.
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "users")
@DynamicInsert // 애노테이션 추가
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id", nullable = false)\
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
@ColumnDefault("'YES'") // default
@Enumerated(EnumType.STRING)
private UsageStatus usageStatus;
}
이제 다시 UsageStatus 값 없이 save를 해보면 다음과 같은 쿼리가 발생한다.
insert into users (name) values ('han2');
null 값은 배제한다.
그리고 DB에는 default value 값이 잘 세팅되어 있는 것을 볼 수 있다.
'java > jpa' 카테고리의 다른 글
[JPA] drop table if exists user cascade " via JDBC (0) | 2024.08.14 |
---|---|
[Spring] JPA 연관관계 - ID 만 사용해서 save (4) | 2022.08.04 |
[JPA] DDL-AUTO 테이블 자동 생성 전략 - SQL Column 매칭 (0) | 2021.06.10 |
[JPA] CommandAcceptanceException: Error executing DDL (0) | 2021.06.10 |
[Spring Data JPA] 나머지 기능들 (0) | 2021.05.31 |