ModelMapper란?
"서로 다른 클래스의 값을 한번에 복사하게 도와주는 라이브러리"
어떤 Object(Source Object)에 있는 필드 값들을 자동으로 원하는 Object(Destination Object)에 Mapping시켜주는 라이브러리이다.
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "ITEM_DETAIL"; SQL statement:
insert into item (item_detail, item_nm, item_sell_status, price, reg_time, stock_number, update_time, item_id) values (?, ?, ?, ?, ?, ?, ?, ?) [23502-199]
개인 토이 프로젝트를 진행하며 상품 등록 테스트를 하던 도중 해당 오류를 발견하였습니다.
ItemFormDto를 Item으로 변환하는 과정 중 제대로 변환이 되지 않고 Item 엔티티 컬럼에 null 값이 반영되어 있는 오류였습니다.
Item 엔티티에는 setter를 사용하지 않으려 setter를 제한하였으며, ItemFormDto에서 Item으로 변환하는 과정에서는 ModelMapper를 사용하였습니다.
@Entity
@Getter
@ToString
@Builder
@AllArgsConstructor
public class Item {
@Id
@Column(name = "item_id")
@GeneratedValue
private Long id;
@Column(nullable = false, length = 50)
private String itemNm;
@Column(nullable = false)
private int price;
@Column(nullable = false)
private int stockNumber;
@Lob
@Column(nullable = false)
private String itemDetail;
@Enumerated(EnumType.STRING)
private ItemSellStatus itemSellStatus;
private LocalDateTime regTime;
private LocalDateTime updateTime;
public Item() {
}
}
-변환 될 Entity
@Getter
@Setter
public class ItemFormDto {
private Long id;
@NotBlank(message = "상품명은 필수 입력 값입니다.")
private String itemNm;
@NotNull(message = "가격은 필수 입력 값입니다.")
private int price;
@NotNull(message = "재고는 필수 입력 값입니다.")
private int stockNumber;
@NotBlank(message = "이름은 필수 입력 값입니다.")
private String itemDetail;
private ItemSellStatus itemSellStatus;
private List<ItemImgDto> itemImgDtoList = new ArrayList<>();
private List<Long> itemImgIds = new ArrayList<>();
private static ModelMapper modelMapper = new ModelMapper();
public Item createItem() {
return modelMapper.map(this, Item.class);
}
public static ItemFormDto of(Item item) {
return modelMapper.map(item, ItemFormDto.class);
}
}
-변환할 Entity
Access level의 default 값이 public이다 따라서 해당 값을 private로 바꿔줄 필요가 있었던 것이었습니다.
public Item createItem() {
return modelMapper.map(this, Item.class);
}
따라서 해당 코드를
public Item createItem() {
modelMapper.getConfiguration()
.setFieldAccessLevel(Configuration.AccessLevel.PRIVATE)
.setFieldMatchingEnabled(true);
return modelMapper.map(this, Item.class);
}
으로 변경하여 오류를 해결해 주었습니다.