Reputation: 1
In Dozer we are able to mention interfaces in hint during field mapping. How can we achieve the same in MapStruct ?
I could not put the exact code here. But, it is the similar as below. We have here an Domain class example:
Class A<T extends B> extends C<T>
{
...
};
Where, B is a abstract class. C is a class which contains a List item which we have to map.
Similar is the structure of the classes and interfaces on DTO side. So, the mapping is as below in Dozer:
<mapping>
<class-a>Domain.A</class-a>
<class-b>DTO.A</class-b>
<field>
<a>item</a>
<b>item</b>
<a-hint>Domain.B</a-hint>
<b-hint>DTO.B</b-hint>
</field>
</mapping>
In MapStruct how do we refer the interfaces as given in the hint in Dozer ?
Scenario: We have:
public class ShopList<T extends Inp> extends Shop<T>\
{ ... };
where,
Inp is a abstract class with no fields in it like:
public abstract class Inp() { };
Shop is a class like:
public class Shop<T extends ShopInp> implements Serializbale
{ private List<T> items = new ArrayList<T>();
//getters and setters for the items };
ShopInp is a public interface with no fields in it like:
public interface ShopInp {} .
We have similar structure of classes on DTO side and Domain side.
Could you please let me know how would the mapper look like for the above scenario ? In general, If we try mapping the ShopList class, then, how do we ensure that the T extends ShopInp and T extends Inp are also being mapped as a part of ShopList?
Upvotes: 0
Views: 822
Reputation: 21393
So called hints can be used via BeanMapping#resultType
. MapStruct can use that to create the instance of the object you are trying to map. However, it will only create mapping for the elements of the abstract class, as it has no other information during compilation time (Dozer uses reflection and can detect the fields of the type during runtime).
Imagine you have this structure
public interface Fruit {
String getName();
String setName(String name);
}
public Apple implements Fruit {
...
}
public Banana implements Fruit {
...
}
public abstract class FruitDto {
private String name;
//getters and setters
}
public AppleDto extends FruitDto {
...
}
public BananaDto extends FruitDto {
...
}
public class Basket {
private Collection<Fruit> fruits;
}
public class BasketDto {
private Collection<FruitDto> fruits;
}
Your mapper can then look like:
@Mapper
public interface BasketMapper {
BasketDto map(Basket basket);
@BeanMapping(resultType = BananaDto.class)
FruitDto map(Fruit fruit);
}
Using this mapper all fruits in the BasketDto
would be of an instance BananaDto
(due to the BeanMapping#resultType
and mapping would only be created for the elements of the FruitDto
Upvotes: 0