【问题标题】:Map an iterable to non-iterable directly to DTO将可迭代到不可迭代直接映射到 DTO
【发布时间】:2017-08-23 09:27:39
【问题描述】:

我有几天一直在使用 MapStruct 1.1,但还没有达到我的需要。

我想要做的是: 我想将 JPA-Entity 映射到 DTO 以在 Primefaces 项目中实现更好的属性视图绑定。

所以我的实体如下:

Patient.java

public class PatientEntity implements Serializable {

    @Id
    private long patid;

    // ...
    // countless properties here
    // ...

    private List<PersonEntity> persons;    // contains a history of persons

    // getters and setters
}

Person.java

public class PersonEntity implements Serializable {

    @Id
    private long personid; // some id

    private String name;

    // other properties + getters/setters
}

我想像这样映射那些实体:

PatientDto.java

public class PatientDto {
    private long patientNumber;

    private Date birthday;

    private PersonDto latestPersonInfo;

    // some other properties + getters/setters
}

PersonDto.java

public class PersonDto {

    private String name;

    private String surname;

    // some other properties + getters/setters
}

我编写了 Mapper 类和一个实用程序,如 GitHub 上的官方示例(https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-nested-bean-mappingshttps://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-iterable-to-non-iterable)中所述,但是当我想执行我的测试用例时(只需创建实体,然后调用映射器,然后调用 assertEquals( ) 单个属性) 我得到了 PersonMapper 的 NullPointerException 但 PatientMapper 成功完成了它的工作,除了 latestPersonInfo 属性。

我的 Mapper 和 utils 如下所示:

LatestPerson.java

@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface LatestPerson {

}

PersonUtil.java

// Returns the one person object i need for the further properties
// returns the latest person object
public class PersonUtil {

    @LatestPerson
    public PersonEntity latest(List<PersonEntity> persons) {

        if (persons != null && !persons.isEmpty()) {
            for (PersonEntity person : persons) {
                if (person.getPbisdatum() == null) {
                    return person;
                }
            }
        }

        return null;
    }
}

PatientMapper.java

@Mapper(uses = PersonUtil.class)
public interface PatientMapper {

    PatientMapper INSTANCE = Mappers.getMapper(PatientMapper.class);

    @Mappings({
        @Mapping(source = "patnr", target = "patientNumber"),
        // other mappings
        @Mapping(source = "persons", target = "latestPersonInfo", qualifiedBy = LatestPerson.class)
    })
    PatientDto fromPatientEntity(PatientEntity patient);

}

PersonMapper.java

public interface PersonMapper {

    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);

    @Mappings({
        @Mapping(source = "panrede", target = "salutation"),
        @Mapping(source = "ptitel", target = "title"),
        @Mapping(source = "pvorname", target = "name"),
        // other mappings
    })
    PersonDto fromPersonEntity(PersonEntity person);

    @InheritInverseConfiguration
    PersonEntity toPersonEntity(PersonDto personDto);

}

所以,我认为嵌套属性会自动转换,但在这种情况下它们似乎不会,我还收到一个编译器错误,告诉我我需要一个映射方法进行转换:PersonDto map(List&lt;PersonEntity&gt; value) 但我我想,我已经使用 utils 提供了这个。

如果有人有任何想法,请告诉我或提供提示以实施一个好的解决方法。

注意: 仅当我更改我的 PersonUtil 以返回 PersonDto 并使用我明确编写的映射器但随后抛出 NullPointerException 因为我的 PersonMapper 无法实例化时,应用程序才会编译。

【问题讨论】:

    标签: dto mapstruct


    【解决方案1】:

    我找到了我的解决方案,我只是没有看到我忘记用@Mapper 注释来注释我的PersonMapper

    但是,如果有人遇到过同样的问题或确实需要相同的功能,那么这种方法会起作用。

    更正 PersonMapper 类:

    PersonMapper.java

    @Mapper    // <- I oversaw to add this
    public interface PersonMapper {
    
      PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
    
        @Mappings({
            @Mapping(source = "panrede", target = "salutation"),
            @Mapping(source = "ptitel", target = "title"),
            @Mapping(source = "pvorname", target = "name"),
            // other mappings
        })
        PersonDto fromPersonEntity(PersonEntity person);
    
        @InheritInverseConfiguration
        PersonEntity toPersonEntity(PersonDto personDto);
    
    }
    

    【讨论】:

    • 很高兴您发现了问题并解决了它:)。一个小插件,目前我正在为 MapStruct 开发一个 IntelliJ 插件,我们将突出显示这样的代码,并显示一个错误,指出缺少 @Mapper@MapperConfig 注释。
    • @Filip 不错,期待发布后尽快试用! :)
    【解决方案2】:

    这样做的其他方式是,无需创建 Qualifier 和 Utils 类。

    PatientMapper.java

    你可以直接使用,

    @Mappings({
        @Mapping(source = "patnr", target = "patientNumber"),
        @Mapping(target = "latestPersonInfo", expression = "java(PersonMapper.INSTANCE.fromPersonEntity(patient.getPersons().get(0)))")
        })
    PatientDto fromPatientEntity(PatientEntity patient);
    

    【讨论】:

      猜你喜欢
      • 2019-08-15
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 2012-04-27
      • 1970-01-01
      • 2017-04-20
      • 1970-01-01
      • 2013-03-23
      相关资源
      最近更新 更多