Java 如何设置嵌套到不同嵌套的ModelMapper?

Java 如何设置嵌套到不同嵌套的ModelMapper?,java,spring,modelmapper,Java,Spring,Modelmapper,飞行对象具有如下属性: @JsonProperty("OriginLocation") private Location originLocation; @JsonProperty("lat") private double latitude; @JsonProperty("lon") private double longitude; private CoordinatesDto coordinates; private double latitude; private double l

飞行对象具有如下属性:

@JsonProperty("OriginLocation")
private Location originLocation;
@JsonProperty("lat")
private double latitude;
@JsonProperty("lon")
private double longitude;
private CoordinatesDto coordinates;
private double latitude;
private double longitude;
位置对象如下所示:

@JsonProperty("OriginLocation")
private Location originLocation;
@JsonProperty("lat")
private double latitude;
@JsonProperty("lon")
private double longitude;
private CoordinatesDto coordinates;
private double latitude;
private double longitude;
我正在映射到FlightDto,属性如下所示(注意:FlightDto将5个左右的属性从flightd移动到LocationDto——这些属性都自动映射,除了lat/long):

LocationDto看起来像这样:

@JsonProperty("OriginLocation")
private Location originLocation;
@JsonProperty("lat")
private double latitude;
@JsonProperty("lon")
private double longitude;
private CoordinatesDto coordinates;
private double latitude;
private double longitude;
协调看起来像这样:

@JsonProperty("OriginLocation")
private Location originLocation;
@JsonProperty("lat")
private double latitude;
@JsonProperty("lon")
private double longitude;
private CoordinatesDto coordinates;
private double latitude;
private double longitude;
所以。。。除lat/long外,所有属性都映射正确。映射应为:

FlightDto.getOrigin().setCoordinates(new CoordinatesDto(Flight.getOriginLocation().getLatitude(),
                             Flight.getOriginLocation().getLongitude());
FlightDto.getOrigin()中还有其他字段以某种方式自动正确映射

我试着做:

    modelMapper.addMappings(new PropertyMap<Flight, FlightDto>() {
        @Override
        protected void configure() {
            map().getOrigin().setCoordinates(new CoordinatesDto(source.getOriginLocation().getLatitude(),
                                                                    source.getOriginLocation().getLongitude()));
//              map().getDestination().setCoordinates(new CoordinatesDto(source.getDestinationLocation().getLatitude(),
//                                                                       source.getDestinationLocation().getLongitude()));

    }
});
modelMapper.addMappings(新属性映射(){
@凌驾
受保护的void configure(){
map().getOrigin().setCoordinates(新坐标DTO(source.getOriginLocation().getLatitude()),
source.getOriginLocation().getLongitude());
//map().getDestination().setCoordinates(新坐标DTO(source.getDestinationLocation().getLatitude()),
//source.getDestinationLocation().getLength());
}
});
但这实际上会在启动时崩溃:

原因:java.lang.NullPointerException:null 在org.xxx.yyy.flights.models.Location$ByteBuddy$NcO8GjcN.getLongitude(未知源)~[classes/:na] 在org.xxx.yyy.config.ModelMapperConfig$2.configure(ModelMapperConfig.java:42)~[classes/:na] 在org.modelmapper.PropertyMap.configure(PropertyMap.java:389)~[modelmapper-2.3.5.jar:na]

我不明白为什么getLatitude()可以工作,但getLatitude()一点都不可以。。。但是假设我在那里注释掉getLongitude()和硬代码1。。。似乎setter在启动时只被调用一次,而不是针对每条记录


我还看到了一些使用TypeMap的示例,但我看不出如何从1个嵌套级别映射到2个嵌套级别,因为LocationDto的创建和填充是正确的,但LocationDto.Coordinates却不正确。

我在使用modelmapper时遇到了类似的问题。我有一个pojo,它有一组相同类型的属性,比如:

私有注册器由;
私人登记处更新人;
私人注册人拥有;
ModelMapper只持有
注册器的一个实例(遇到的第一个实例,即使它为空)

我的解决方案是使用
Converter
s并使用原语类型映射原始值

然后,映射看起来像:

addMappings(新属性映射(){
@凌驾
受保护的void configure(){
使用(registerFromId).map(source.getregisterId()).setregister(null);
使用(registerFromid).map(source.getUpdateId()).setUpdater(null);
使用(registerFromId).map(source.getCreatorId()).setCreator(null);
}
});
使用此转换器:

private final Converter registerFromid=context->{
MappingContext parent=context.getParent();
if(parent.getDestinationType()==register.class
&&parent.getDestination()!=null){
注册器注册器=(注册器)父级.getDestination();
报税注册主任;
}
Long id=context.getSource();
注册器注册器=注册器daoservice.findById(id);
如果(注册器==null){
抛出新的MappingException(String.format(“未找到注册器%s”,id));
}
报税注册主任;
};

我希望这能激励您找到解决方案。

我在使用modelmapper时遇到了类似的问题。我有一个pojo,它有一组相同类型的属性,比如:

私有注册器由;
私人登记处更新人;
私人注册人拥有;
ModelMapper只持有
注册器的一个实例(遇到的第一个实例,即使它为空)

我的解决方案是使用
Converter
s并使用原语类型映射原始值

然后,映射看起来像:

addMappings(新属性映射(){
@凌驾
受保护的void configure(){
使用(registerFromId).map(source.getregisterId()).setregister(null);
使用(registerFromid).map(source.getUpdateId()).setUpdater(null);
使用(registerFromId).map(source.getCreatorId()).setCreator(null);
}
});
使用此转换器:

private final Converter registerFromid=context->{
MappingContext parent=context.getParent();
if(parent.getDestinationType()==register.class
&&parent.getDestination()!=null){
注册器注册器=(注册器)父级.getDestination();
报税注册主任;
}
Long id=context.getSource();
注册器注册器=注册器daoservice.findById(id);
如果(注册器==null){
抛出新的MappingException(String.format(“未找到注册器%s”,id));
}
报税注册主任;
};

我希望这能激励您找到解决方案。

我认为您在这里有两个问题,请参见下面的代码和注释:

// When you have different field names you should tell it to ModelMapper like this
mm.createTypeMap(Flight.class, FlightDto.class).addMapping(Flight::getOriginLocation,
    FlightDto::setOrigin);

// And when you do not have 'clear' association or mapping is not in the `same 
// level` mapping can not be guessed so you need to tell it explicitly like 
// (this is something near to what you tried already)
mm.addMappings(new PropertyMap<Location, LocationDto>() {
    @Override
    protected void configure() {
        map().getCoordinates().setLatitude(source.getLatitude());
        map().getCoordinates().setLongitude(source.getLongitude());
    }
});
//当您有不同的字段名时,应该像这样告诉ModelMapper
mm.createTypeMap(Flight.class,FlightDto.class).addMapping(Flight::getOriginLocation,
FlightDto::setOrigin);
//当您没有“清除”关联或映射时,它们不在“相同”中
//level`映射无法猜测,因此您需要像下面这样明确地告诉它
//(这与您已经尝试过的内容非常接近)
mm.addMappings(新属性映射(){
@凌驾
受保护的void configure(){
map().getCoordinates().setLatitude(source.getLatitude());
map().getCoordinates().setLongitude(source.getLongitude());
}
});

在讲了这些(这两个)之后-假设我正确理解了您的模型/dto结构-
ModelMapper
能够进行映射

我认为这里有两个问题,请参见下面的代码和注释:

// When you have different field names you should tell it to ModelMapper like this
mm.createTypeMap(Flight.class, FlightDto.class).addMapping(Flight::getOriginLocation,
    FlightDto::setOrigin);

// And when you do not have 'clear' association or mapping is not in the `same 
// level` mapping can not be guessed so you need to tell it explicitly like 
// (this is something near to what you tried already)
mm.addMappings(new PropertyMap<Location, LocationDto>() {
    @Override
    protected void configure() {
        map().getCoordinates().setLatitude(source.getLatitude());
        map().getCoordinates().setLongitude(source.getLongitude());
    }
});
//当您有不同的字段名称时