简体   繁体   中英

MapStruct object inheritance mapping

I have a given scenario like below

> class Curve {
      private List<Point> points = new ArrayList<>();
  }

> class Points {
      private Axis xAxis;
      private Axis yAxis;
      private Axis zAxis;
   }

> abstract class Axis {}

> class XAxis extends Axis {}
> class YAxis extends Axis {}
> class ZAxis extends Axis {}

I am creating a Mapper for Curve class like :

@Mapper
public interface CurveMapper {

 CurveMapper INSTANCE = Mappers.getMappers(CurveMapper.class);
 
 com.entity.Curve map(com.dto.Curve dtoCurve);    

}

The build fails asking for concrete class/Object factory for Axis class.

I can add the objectFactory for Axis class but how can I map all 3 different concrete classes by single objectFactory .

The simplest solution obviously is to use concrete types on classes:

> class Curve {
      private List<Point> points = new ArrayList<>();
  }

> class Points {
      private XAxis xAxis;
      private YAxis  yAxis;
      private ZAxis zAxis;
   }

> abstract class Axis {}

> class XAxis extends Axis{}
> class YAxis extends Axis{}
> class ZAxis extends Axis{}

Otherwise you should have a look in qualifiers

Define the following class:

public class AxisMapper {

    public Axis xAxis(AxisDto dto) {
        // some mapping logic, including new object creation
    }

}

Define the qualifier for general axis handling:

import org.mapstruct.Qualifier;

@Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface AxisTranslator{
}

And the qualifier for methods (one per axis):

import org.mapstruct.Qualifier;

@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface XAxis{
}

Decorate your custom mapper:

@AxisTranslator
public class AxisMapper {

    @XAxis
    public Axis xAxis(AxisDto dto) {
        // some mapping logic, including new object creation
    }

}

And then, add this new mapper to your one:

@Mapper(uses = AxisMapper.class)
public interface CurveMapper {

 CurveMapper INSTANCE = Mappers.getMappers(CurveMapper.class);
 
 @Mapping( target = "xAxis", qualifiedBy = { AxisTranslator.class, XAxis.class } )
 com.entity.Curve map(com.dto.Curve dtoCurve);    

}

Do the same for Y and Z axis.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM