Reputation: 3953
I am using spring-boot-1.5.6 and modelmapper-1.1.0. I would like to map the entity object to OrderDto but don't know how to do it via modelMapper. Please find the below code
Order.Java
public class Order {
private String orderUid;
private Invoice invoice;
private List<Item> items;
//Getter & setter
}
Item.java
public class Item {
private String itemId;
private String itemName;
private String itemUid;
private String isbn;
//other details of item
//Getter & setter
}
OrderDTO.java
public class OrderDTO {
private String orderUid;
private Invoice invoice;
private String itemId;
private String itemName;
private String itemUid;
private String isbn;
//other details of item
//Getter & setter
}
I would like to return OrderDTO with the item based on the itemID we are getting from the client(FrontEnd)
public Page<OrderDTO> convertOrderEntityToDTO (Page<Order> orderList,String itemId) {
ModelMapper modelMapper = new ModelMapper();
Type listType = new TypeToken<Page<OrderDTO>>() {}.getType();
modelMapper.addConverter((MappingContext<Order, OrderDTO> context) -> {
Item item = context.getSource().getItems().stream()
.filter(item -> equalsIgnoreCase(item.getItemId,itemId))
.findAny().orElse(null);
if (item != null) {
OrderDTO orderDTO = context.getDestination();
orderDTO.setItemId(item.getItemId());
orderDTO.setItemName(item.getItemName());
orderDTO.setItemUid(item.getItemUid());
orderDTO.setIsbn(item.getIsbn());
return orderDTO;
}
return null;
});
Page<OrderDTO> addonServices = modelMapper.map(orderList, listType);
}
In the above method, converter was never called(may be because of incorrect TypePair of modelMapper) and the item related attributes in OrderDTO is always null. I would like to get the Item value based on ItemId.
Any help or hint would be appreciable. Any suggestion with or without modelMapper would be really appreciable.
Upvotes: 3
Views: 2210
Reputation: 7361
If you are using Spring Data JpaRepositories
to retrieve data from the database you can make a repository method that creates a DTO for you. Such a method would look something like this:
@Query("SELECT new full.path.OrderDTO(s.itemId, s.itemName, s.itemUid) FROM Item s WHERE s.itemId = :id")
public OrderDTO getOrderDTOByItemId(@Param("id") long id);
The method should go in the jparepository class you use to retrieve Item
instances from the database with. To make this work your OrderDTO needs to have a constructor with this parameter list. ( long itemId, String itemName, String itemUid)
. The parameters need to be in the same order as (s.itemId, s.itemName, s.itemUid)
. Also always make sure you create a default constructor as well when you create a constructor with parameters.
Upvotes: 0
Reputation: 4869
As far as I understand, you use Page
class of org.springframework.data
or something like that. Anyway, this generic Page
class contains generic List
with your data. I would say, that this construction is just "too generic" for modelMapper. You'd better get list of your data, convert it and create a new Page
.
Furthermore
You should create a typeMap
to register a new converter
context.getDestination()
returns not null if you provide new destination object by modelMapper.map(..)
. In your case you'll get null
.
This is my vision of your convertOrderEntityToDTO
method:
public Page<OrderDTO> convertOrderEntityToDTO(Page<Order> orderList, String itemId) {
ModelMapper modelMapper = new ModelMapper();
modelMapper.createTypeMap(Order.class, OrderDTO.class)
.setConverter(context -> context.getSource().getItems().stream()
.filter(o -> equalsIgnoreCase(o.getItemId(), itemId))
.findAny().map(o -> {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setItemId(o.getItemId());
orderDTO.setItemName(o.getItemName());
orderDTO.setItemUid(o.getItemUid());
orderDTO.setIsbn(o.getIsbn());
return orderDTO;
}).orElse(null));
List<OrderDTO> orderDtoList = orderList.getContent().stream()
.map(o -> modelMapper.map(o, OrderDTO.class))
.collect(Collectors.toList());
return new PageImpl<>(orderDtoList, orderList.getPageable(), orderList.getTotalElements());
}
Upvotes: 1