Table of Contents
JPA 기본값, 변경된 필드만 업데이트
JPA 기본값
@ColumnDefault("0")
과 @Column(nullable = false)
는 테이블 스키마 생성에만 관여한다.
insert 값이 null 인 경우 기본값으로 자동입력 해주는 기능은 없다.
private Integer likeCount = 0;
과 같이 기본값을 설정해 주어야 한다.
@Entity
@Getter
@Setter
@Table(name = "MEDIA")
@NoArgsConstructor
public class Media {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "idx")
private Long idx;
@ColumnDefault("0")
@Column(nullable = false)
private Integer likeCount = 0;
@NotNull
@ColumnDefault("0")
private BigDecimal price = BigDecimal.ZERO;
@Builder
public Media(Integer likeCount) {
this.likeCount = likeCount;
}
}
@Column(nullable = false)
은 테이블 스키마 생성에만 관여한다.
null 값 체크는 실제로 insert 하는 시점에 DB 에서 체크된다.
@NotNull
은 DB 에서 체크되는 것이 아니라, JPA 에서 체크된다. 또한 아래 의존성이 추가되어야 한다.
dependencies {
// ......
compile('org.springframework.boot:spring-boot-starter-validation')
// ......
}
변경된 필드만 업데이트
JPA 는 null 값이 명시적으로 null 값으로 설정하는 것인지 아니면 단지 값을 입력하지 않아 null 인지를 구분하지 못한다.
변경이 필요한 필드를 업데이트 하려면, PK 를 이용에 Entity 전체를 불러와서, 변경이 필요한 필드를 명시적으로 업데이트(코딩)해야 한다.
null 이 아닌 필드만 업데이트 하기
mapstruct
를 이용해 null 이 아닌 필드만 업데이트 할 수 있다.
아래의 의존성이 추가로 필요하다.
dependencies {
// ......
implementation 'org.mapstruct:mapstruct:1.4.1.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.1.Final'
// ......
}
Dto 는 반대로 디폴트 값 설정을 하면 안된다.
@Setter
@Getter
@NoArgsConstructor
public class MediaDto {
private Long idx;
private Integer likeCount;
private BigDecimal price;
}
매핑시 null 인 필드를 무시한다.
@Mapper(componentModel = "spring")
public interface MediaMapper {
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void updateMediaFromDto(MediaDto dto, @MappingTarget Media entity);
}
@Test
public void test2() {
Media media = new Media();
Media resultMedia = mediaRepository.save(media);
MediaDto mediaDto = new MediaDto();
mediaDto.setPrice(BigDecimal.valueOf(5000));
mediaMapper.updateMediaFromDto(mediaDto, resultMedia);
Media resultMedia2 = mediaRepository.save(media);
MatcherAssert.assertThat(resultMedia2.getPrice(), Is.is(BigDecimal.valueOf(5000)));
}
포스팅 잘 읽었습니다. Mapstruct 적용중에 의문이 잇어 글을 남기게 되었어요.
Mapper 를 Dto 나 Entity 내부에 포함한 다음, toDto() 또는 toEntity() 로 반환되게 하는 방식은
특별한 문제가 있을까요? Entity 매핑의 경우는 ENtityManager 가 포함된 매퍼 라야 하는 제한은 있습니다만..
toXxxx() 방식에 문제점이 어떤게 있을지 의견이 궁금합니다.