[java] ModelMapper 사용기 By starseat 2022-07-19 18:22:17 java/spring Post Tags `Spring Boot` 로 `API Server` 를 만드는 중 `DTO` 를 `Entity`로 변환하기가 번거로워 `ModelMapper`를 도입하게 되었다. 먼저 `gradle project` 이니 `dependencies` 에 `ModelMapper` 를 추가 하였다. - build.gradle ``` dependencies { // ModelMapper implementation 'org.modelmapper:modelmapper:3.1.0' } ``` `dependencies`에 추가해 줬으니 이제 사용을 위한 준비를 하자! 해당 `class`에 `ModelMapper modelMapper = new ModelMapper()` 를 하여도 되나 `Spring Boot`를 사용하니 `Bean` 등록을 해주자! ``` @Bean public ModelMapper modelMapper() { ModelMapper modelMapper = new ModelMapper(); // 약간의 옵션 추가 modelMapper.getConfiguration() .setMatchingStrategy(MatchingStrategies.STRICT) .setSkipNullEnabled(true); return modelMapper; } ``` 이제 진짜 사용해보자! - `SampleService.java` ``` @Service @RequiredArgsConstructor public class SampleService { private final ModelMapper modelMapper; private final SampleRepository repository; public String insert(SampleDto dto) { SampleEntity entity = modelMapper.map(dto, SampleEntity.class); return repository.insert(entity); } } ``` ~~잘 된다.~~ 잘 되는 줄 알았는데 그게 아니였다. 개발 상황을 덧붙이면 DB 는 `MongoDB` 를 사용 하고 있다. 그리고 `ObjectId` 값도 받는 항목이 있다. - SampleDto.java ``` @Getter @Setter @Builder @ToString @NoArgsConstructor @AllArgsConstructor public class SampleDto { private String id; private String groupId; private String name; ... } ``` - SampleEntity.java ``` @Getter @Setter @Builder @ToString @NoArgsConstructor @AllArgsConstructor public class SampleEntity { private ObjectId id; private ObjectId groupId; private String name; ... public void setId(String id) { this.id = new ObjectId(id); } public void setId(ObjectId id) { this.id = id; } public void setGroupId(String groupId) { this.groupId = new ObjectId(groupId); } public void setGroupId(ObjectId groupId) { this.groupId = groupId); } ... } ``` `SampleEntity` 를 보면 `id` 와 `groupId` 가 `ObjectID` 로 되어 있다. 위 `SampleService` 에서 dto 를 entity 로 변환하는 부분에서 `gorupId` 가 `null` 이 되는 현상이 발생하였다. - `SampleService.insert` 의 문제되는 상황 ``` public String insert(SampleDto dto) { // dto: { id: null, groupId: "625cbe97fda5ab40b5f61fae", name: "test", ... } SampleEntity entity = modelMapper.map(dto, SampleEntity.class); // entity: { id: null, groupId: null, name: "test", ... } return repository.insert(entity); } ``` 큰일이다... `groupId` 가 `null` 이면 안되는데... 구글링 하면서 방법을 찾았다!! `ModelMapper` 에 설정을 추가하였다. ``` @Bean public ModelMapper modelMapper() { ModelMapper modelMapper = new ModelMapper(); modelMapper.getConfiguration() .setMatchingStrategy(MatchingStrategies.STRICT) .setSkipNullEnabled(true); // 이 부분 추가 modelMapper.addConverter(new AbstractConverter() { @Override protected ObjectId convert(String source) { return source == null ? null : new ObjectId(source); } }); return modelMapper; } ``` `ModelMapper` 수정 후 지금까지는 잘 변환되고 있는데 문제가 생기면 수정 후 블로그도 업데이트 해야겠다. ### Reference - [http://modelmapper.org/getting-started/](http://modelmapper.org/getting-started/) - [https://stackoverflow.com/questions/44534172/how-to-customize-modelmapper](https://stackoverflow.com/questions/44534172/how-to-customize-modelmapper) - [https://www.baeldung.com/java-modelmapper](https://www.baeldung.com/java-modelmapper) Previous Post [java] Camel Case(카멜 케이스/캐멀 케이스) 변환 Next Post [spring] @Bean 선택적 사용