본문 바로가기
IT 이야기/Java

JPA Default value 적용 - @DynamicInsert

by Dblog 2021. 7. 20.
728x90

JPA를 적용하면서 생겼던 Default Constraint관련 이슈를 정리합니다.

 

DB의 테이블을 설계할 때 default value 설정이 필요한 순간이 있습니다.
계정의 활성화 상태를 false로 설정하거나, 성별을 선택하지 않으면 'M'으로 설정하는 Null인 상태로 유지할 수 없는 필드의 경우 default 값 설정이 필요합니다.

이럴 때 Table을 생성할 때 Default Constraint를 설정하게 되는데

CREATE TABLE 'member' (
    'id' binary(16),
    'username' varchar(255),
    'social' varchar(255) DEFAULT 'LOCAL',
    PRIMARY KEY('id')
);

형태를 가지게 됩니다. DDL에 Default를 설정하면 데이터를 insert 할 때 값을 입력하지 않으면 자동으로 'LOCAL'이라는 값을 입력하게 됩니다.

JPA로 Table을 작성할때 Default값을 설정하는 방법은 몇 가지 있지만 @Column 어노테이션으로 설정하는 방법을 사용했습니다.

@Entity
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Getter
@Setter
@Data
public class Member {

    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(columnDefinition = "BINARY(16)")
    @ColumnDescription("PK")
    private UUID id;
    
    private String username;


    @Enumerated(EnumType.STRING)
    @Column(columnDefinition = "varchar(255) default 'LOCAL'")
    private Social social;

}

 

그런데  문제가 발생합니다. 데이터에 default value가 아닌, null 값이 입력되고 있습니다.

log를 확인해보면 입력하지 않은 필드는 null 값이 insert 되고 있음을 확인할 수 있습니다.

null 값을 해결하기위해 가장 먼저 생각나는 방법은 save() 하기 전에 default value로 setter를 이용해 설정하는 방법이었습니다.

Member member = new Member();
member.setSocial("LOACL");

그러나 이 방법을 사용하려고 DDL에 default를 넣은 게 아닙니다. 이런 방법으로 하려 했으면 default를 설정할 필요가 없습니다.

 

해결방안으로 저는 @DynamicInsert를 사용하기로 했습니다.

기존 방식으로 데이터를 save 하면 객체에 저장되어있는 null까지 함께 save 하기 때문에 default value 이슈가 생겼습니다. 그런데 DynamicInsert는 null 값인 field를 제외하고 insert 하기 때문에 실제로 DB에 설정된 default 값이 저장됩니다.

사진에서 보면 값을 넣지 않은 social의 경우는 insert into 쿼리에 없는 것을 확인할 수 있습니다. 

DB에도 값이 잘 들어가는 것을 확인할 수 있었습니다.

 


※ PS.

@DynamicUpdate 도 update 할 때 null에 해당하는 값을 빼고 업데이트하기 때문에 null 이슈에 대한 대응책으로 활용할 수 있습니다.

 

 

 

 

 

 

 

728x90

댓글