1. @ColumnDefault만 붙이면 자동으로 default 값이 저장될 줄 알았다고요
User라는 엔티티가 있다.
기본적인 필드들이 있다.
package com.spring.dozen.auth.domain.entity;
import com.spring.dozen.auth.domain.enums.Role;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(access = AccessLevel.PRIVATE)
@Entity
@Table(
name = "p_user",
uniqueConstraints = {
@UniqueConstraint(name = "UK_USER", columnNames = {"username"})
}
)
public class User extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(name = "username", length = 10, nullable = false)
private String username;
@Column(name = "password", length = 60, nullable = false)
private String password;
@Column(name = "slack_id", length = 30, nullable = false)
private String slackId;
@Column(name = "role", nullable = false)
@Enumerated(EnumType.STRING)
private Role role;
// 승인 여부
@Column(name = "is_approved", nullable = false)
@ColumnDefault("false")
private Boolean isApproved;
}
맨 아래에 isApproved
승인이 되었는지 승인이 안 되었는지를 판단하는 필드를 추가했다.
나는 @ColumnDefault("false") 라고 선언하면
해당 값을 세팅하지 않아도 자동으로 false가 저장될 줄 알았다.
근데 안되네?
2. @ColumnDefault는 데이터베이스 레벨에서 동작하는 제약조건이다.
그렇다고 한다.
@ColumnDefault는 DDL문이 적용될 때 적용된다.
따라서, 현재 application.yml 에 ddl-auto 가 update 인 상태의 경우 default 값이 적용되지 않는다.
3. JPA의 기본 동작을 생각하면, @DynamicInsert도 있어야 한다.
JPA의 기본 전략은 insert를 요청하지 않은 필드도 모두 삽입되도록 한다는 것이다.
이 때, 값을 지정하지 않은 필드는 당연하게도 null이 들어간다.
@DynamicInsert가 클래스 레벨에 붙어 있어야, 지정한 값만 들어가기 때문에 기본값이 적용된다.
4. 사용하기 조금 번거롭네?
그래서 그냥, User를 생성할 때 isApproved를 false로 넣도록 했다.
public static User create(String username, String password, String slackId, Role role, Boolean isApproved) {
return User.builder()
.username(username)
.password(password)
.slackId(slackId)
.role(role)
.isApproved(isApproved)
.build();
}
public static User create(String username, String password, String slackId, Role role) {
return create(username, password, slackId, role, false);
}
나는 생성자나 빌더패턴 대신 정적 팩토리 메서드를 선호한다.
isApproved를 받는 create(), 안 받는 create()를 만들어서 사용하고 있다.