ModelMapper란?

"서로 다른 클래스의 값을 한번에 복사하게 도와주는 라이브러리"
어떤 Object(Source Object)에 있는 필드 값들을 자동으로 원하는 Object(Destination Object)에 Mapping시켜주는 라이브러리이다.

 

http://modelmapper.org/

 

ModelMapper - Simple, Intelligent, Object Mapping.

Why ModelMapper? The goal of ModelMapper is to make object mapping easy, by automatically determining how one object model maps to another, based on conventions, in the same way that a human would - while providing a simple, refactoring-safe API for handli

modelmapper.org

 

 

 

 

 

 

 

 

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);
    }

으로 변경하여 오류를 해결해 주었습니다.

 

 

 

 

 

참조 블로그

+ Recent posts