VelNaga
VelNaga

Reputation: 3953

Spring boot issue with mapping entity to entityDTO

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

Answers (2)

Maurice
Maurice

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

Feedforward
Feedforward

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

Related Questions