본문 바로가기

BackEnd : Spring/SpringBoot

[SpringBoot] JPA @ColumnDefault, @Builder.Default

@DynamicInsert
@Getter
@Entity
@Table(name="MemoryStar")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class MemoryStar {

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

    @OneToOne
    @JoinColumn(name = "star_id", nullable = true) 
    @OnDelete(action = OnDeleteAction.SET_NULL)
    private StarList starList;

    @Column(nullable = false)
    private String name;

    private ActivityCtg activityCtg;

    private EmotionCtg emotionCtg;

    private String content;

    @CreatedDate
    private LocalDateTime createdAt;

    @ColumnDefault("false")
    private Boolean shared;

    @ColumnDefault("0")
    private Long likes;

    @ColumnDefault("0")
    private Long commentNumber;


}

해당 프로젝트에서 Post 역할을 하는 MemoryStar에서 생성 시 likes는 0, commentNumber는 0으로 default 값으로 적용되도록 하고 싶었는데, @ColumnDefault 어노테이션을 적용해도 default 값이 적용이 안되어서 해결해 보려고 한다.

@ColumnDefault

결론적으로, 내가 ColumnDefault에 대해 잘못 이해하고 있었다.

내가 구현하고 싶었던 건 Entity가 생성될 때 해당 필드에 null이 전달되었을 때 ex) DTO에 해당 값이 전달되지 않았을 때

Default 값으로 좋아요 개수를 0으로 설정하고 싶었던 것이었다.

@ColumnDefault는 데이터베이스 수준에서 기본값을 제공하는 것이며, JPA나 Hibernate가 자동으로 Java 객체수준에서 값을 설정하는 것이 아니기 때문에 디폴트 값이 들어가는 것이 아닌 null 값이 할당된다.

특징

데이터베이스 테이블을 생성할 때 기본값을 설정하는 역할을 함.

Java 코드에서 직접적인 기본값을 적용하지 않음 (즉, new Entity()로 생성 시 기본값이 적용되지 않음).

JPA가 SQL CREATE TABLE 문을 생성할 때만 사용됨.

spring.jpa.hibernate.ddl-auto=update일 때는 기존 컬럼에는 적용되지 않음.

@Builder.Default

나는 Builder를 통해 객체를 생성하도록 구현하였기 때문에 Builder.Default 어노테이션을 사용해 각 필드의 default 값들을 할당해 주었다.

    @Builder.Default
    @Column(nullable = false)
    private Boolean shared = false;  // 기본값 설정

    @Builder.Default
    @Column(nullable = false)
    private Long likes = 0L;  // 기본값 설정

    @Builder.Default
    @Column(nullable = false)
    private Long commentNumber = 0L;  // 기본값 설정

특징

Lombok의 @Builder를 사용할 때만 작동하는 기본값 설정 기능.

Java 코드에서 객체를 생성할 때(.builder()) 자동으로 기본값을 적용.

@Builder가 적용된 클래스에서, 해당 필드가 빌더를 통해 설정되지 않을 경우 기본값을 유지.

결론

    @Builder.Default
    @ColumnDefault("false")
    @Column(nullable = false)
    private Boolean shared = false;  // 기본값 설정

    @Builder.Default
    @ColumnDefault("0")
    @Column(nullable = false)
    private Long likes = 0L;  // 기본값 설정

    @Builder.Default
    @ColumnDefault("0")
    @Column(nullable = false)
    private Long commentNumber = 0L;  // 기본값 설정

@ColumnDefault를 사용하여 테이블 생성 시 기본값도 설정해주고,

객체 생성 시 null 값을 방지하면서 초기값을 설정해 주기 위해 @Builder.Default도 사용하였다.

우려되는 점

엔티티가 처음 생성되었을 때 댓글 수 = 0, 좋아요 수 = 0, 공유 여부 = false로 지정해놓기 위해 이런 로직을 추가한 것인데, 

@Builder.Default를 설정하면 초기에 엔티티가 생성되지 않았더라도 엔티티 생성 시 null값이 전달될 때 해당 값으로 생성될 것 같기도 하다.

MemoryStar 엔티티가 생성되는 로직이 사용자가 글을 쓸 때 말고는 따로 생성되지 않을 것 같긴 한데, 추후에 고려해봐야 할 사항이 되겠다.