简体   繁体   English

使用Orika在包含List的两个对象之间进行映射

[英]Mapping between two objects that contain a List using Orika

I am trying to use Orika to map between two objects that contain a List<...> where the List type is another object, however despite trying various permutations of the mapping configuration in mapperFactory.classMap(...) Orika throws an exception when I run my program. 我试图使用Orika在包含List<...>两个对象之间进行映射,其中List类型是另一个对象,但是尽管尝试了mapperFactory.classMap(...)映射配置的各种排列, mapperFactory.classMap(...)会抛出异常当我运行我的程序。

Looking at http://orika-mapper.github.io/orika-docs/mappings-via-classmapbuilder.html it seems to suggest that that syntax for mapping a List should be parentProperty{childProperty} . 看看http://orika-mapper.github.io/orika-docs/mappings-via-classmapbuilder.html似乎建议用于映射List语法应该是parentProperty{childProperty}

For the purposes of this question I've simplified the objects that I'm trying to map. 出于这个问题的目的,我简化了我想要映射的对象。 The source object is ToDoTaskListEntity and the destination object is ToDoTaskListDTO . 源对象是ToDoTaskListEntity ,目标对象是ToDoTaskListDTO The source object ToDoItemEntity contains a List which is defined as List<ToDoItemEntity> and the destination object contains a corresponding List which is defined as List<ToDoItemDTO> 源对象ToDoItemEntity包含一个List,它定义为List<ToDoItemEntity> ,目标对象包含一个相应的List,定义为List<ToDoItemDTO>

My question is how should I define the mapping configuration in Orika between ToDoTaskListEntity and ToDoTaskListDTO so that the child object List<ToDoItemEntity> is also mapped to List<ToDoItemDTO> within their respective parent objects? 我的问题是如何在ToDoTaskListEntity定义ToDoTaskListEntityToDoTaskListDTO之间的映射配置,以便子对象List<ToDoItemEntity>也映射到其各自父对象中的List<ToDoItemDTO>


The code for my mapping configuration is as follows: 我的映射配置的代码如下:

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

mapperFactory.classMap(ToDoItemEntity.class, ToDoItemDTO.class)
    .field("id", "id")
    .field("description", "description")
    .field("status", "status")
    .byDefault()
    .register();

mapperFactory.classMap(ToDoTaskListEntity.class, ToDoTaskListDTO.class)
    .field("listName", "listName")
    .field("toDoItems{id}", "toDoItems{id}")
    .field("toDoItems{description}", "toDoItems{description}")
    .field("toDoItems{status}", "toDoItems{status}")
    .byDefault()
    .register();

The code for invoking the mapping is as follows: 调用映射的代码如下:

MapperFacade mapper = mapperFactory.getMapperFacade();
ToDoTaskListDTO toDoTaskListDTO = mapper.map(toDoTaskListEntity, ToDoTaskListDTO.class);

The code for my source objects is as follow: 我的源对象的代码如下:

public class ToDoTaskListEntity {

    private String ListName;
    private List<ToDoItemEntity> toDoItems;

    // Getters and setters
}

public class ToDoItemEntity {

    private int id;
    private String description;
    private Status status;

    // Getters and setters
}

The code for my destination objects is as follow: 我的目标对象的代码如下:

public class ToDoTaskListDTO {

    private String listName;
    private List<ToDoItemDTO> toDoItems;

    public ToDoTaskListDTO(String listName, List<ToDoItemDTO> toDoItems) {
        this.listName = listName;
        this.toDoItems = toDoItems;
    }

    //Getters but no setters

}

public class ToDoItemDTO {

    private int id;
    private String description;
    private Status status;

    public ToDoItemDTO(int id, String description, Status status) {
        this.id = id;
        this.description = description;
        this.status = status;
    }

    // Getters but no setters
}

The exception that thrown by Orika is as follow: Orika抛出的例外情况如下:

Exception in thread "main" ma.glasnost.orika.MappingException: exception while creating object factory for test.orikademo.ToDoTaskListDTO
-----begin dump of current state-----------------------------
Registered object factories: 1 (approximate size: 25.4 kB)
  [ToDoTaskListDTO] : {}
-------------------------------------------------------------
Registered mappers: 2 (approximate size: 961.5 kB)
  [0] : GeneratedMapper<ToDoItemEntity, ToDoItemDTO> {usedConverters: [], usedMappers: [], usedMapperFacades: [], usedTypes: [] }
  [1] : GeneratedMapper<ToDoTaskListEntity, ToDoTaskListDTO> {usedConverters: [], usedMappers: [], usedMapperFacades: [DefaultBoundMapperFacade<ToDoItemEntity, ToDoItemDTO>], usedTypes: [List<ToDoItemEntity>, List<ToDoItemDTO>] }
-------------------------------------------------------------
Registered concrete types: 5 (approximate size: 122.4 kB)
  [interface java.util.List] : ArrayList<Object>
  [interface java.util.Set] : LinkedHashSet<Object>
  [interface java.util.Collection] : ArrayList<Object>
  [interface java.util.Map$Entry] : MapEntry<Object, Object>
  [interface java.util.Map] : LinkedHashMap<Object, Object>
-------------------------------------------------------------
Resolved strategies: 0 (approximate size: 0.8 kB)
-------------------------------------------------------------
Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@292a74d5
-----end dump of current state-------------------------------
    at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.build(ObjectFactoryGenerator.java:110)
    at ma.glasnost.orika.impl.DefaultMapperFactory.lookupObjectFactory(DefaultMapperFactory.java:1005)
    at ma.glasnost.orika.impl.DefaultMapperFactory.lookupObjectFactory(DefaultMapperFactory.java:925)
    at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMappingStrategy(MapperFacadeImpl.java:218)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:734)
    at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:714)
    at test.orikademo.App.main(App.java:54)
Caused by: java.lang.NullPointerException
    at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.addSourceClassConstructor(ObjectFactoryGenerator.java:173)
    at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.addCreateMethod(ObjectFactoryGenerator.java:124)
    at ma.glasnost.orika.impl.generator.ObjectFactoryGenerator.build(ObjectFactoryGenerator.java:95)
    ... 6 more

I posted the same question in the Orika discussion group on Google Groups and got the following answer from Sidi Mohamed which solved my problem. 我在Google网上论坛的Orika讨论组中发布了同样的问题,并从Sidi Mohamed那里得到了以下答案,解决了我的问题。

You do not need any specific mappings for this example, the only issue I can see here is the non default constructor on the DTO side 这个例子你不需要任何特定的映射,我在这里看到的唯一问题是DTO端的非默认构造函数

 MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); // item class map mapperFactory.classMap(ToDoItemEntity.class, ToDoItemDTO.class) .constrcutorB("id", "description", "status") .byDefault() .register(); mapperFactory.classMap(ToDoTaskListEntity.class, ToDoTaskListDTO.class) .constructorB("listName", "toDoItems") .byDefault() .register(); 

To answer your question the expression like toDoItems{id} is used only to project (or flatten) your objects, in this example what you want is to re use your previous mapping definitions (eg. reuse item class map when mapping toDoItems in the second class map) which why Orika is used : to reduce the boilerplate code. 要回答你的问题,像toDoItems {id}这样的表达式只用于投影(或展平)你的对象,在这个例子中你想要的是重新使用你以前的映射定义(例如,在第二个映射到DoItems时重用项类映射) class map)使用Orika的原因:减少样板代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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