java 推土机深度映射不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/3018006/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dozer deep mapping not working
提问by user363900
I am trying to use dozer 4.1 to map between classes. I have a source class that looks like this:
我正在尝试使用推土机 4.1 在类之间进行映射。我有一个看起来像这样的源类:
    public class initRequest{
     protected String id;
     protected String[] details
}
I have a destination class that looks like this:
我有一个如下所示的目标类:
public class initResponse{
       protected String id;
       protected DetailsObject detObj;
}
public class DetailsObject{
 protected List<String>  details;
}
So essentially i want the string in the details array to be populated into the List in the Details object.
所以基本上我希望将 details 数组中的字符串填充到 Details 对象中的 List 中。
I have tried a mapping like this:
我试过这样的映射:
<mapping wildcard="true" >
  <class-a>initRequest</class-a>
  <class-b>initResponse</class-b>   
  <field>
    <a is-accessible="true">details</a>
    <b is-accessible="true">detObj.details</b>
  </field>
</mapping>
But I get this error:
但我收到此错误:
Exception in thread "main" net.sf.dozer.util.mapping.MappingException: java.lang.NoSuchFieldException: detObj.details
    at net.sf.dozer.util.mapping.util.MappingUtils.throwMappingException(MappingUtils.java:91)
    at net.sf.dozer.util.mapping.propertydescriptor.FieldPropertyDescriptor.<init>(FieldPropertyDescriptor.java:43)
    at net.sf.dozer.util.mapping.propertydescriptor.PropertyDescriptorFactory.getPropertyDescriptor(PropertyDescriptorFactory.java:53)
    at net.sf.dozer.util.mapping.fieldmap.FieldMap.getDestPropertyDescriptor(FieldMap.java:370)
    at net.sf.dozer.util.mapping.fieldmap.FieldMap.getDestFieldType(FieldMap.java:103)
    at net.sf.dozer.util.mapping.util.MappingsParser.processMappings(MappingsParser.java:95)
    at net.sf.dozer.util.mapping.util.CustomMappingsLoader.load(CustomMappingsLoader.java:77)
    at net.sf.dozer.util.mapping.DozerBeanMapper.loadCustomMappings(DozerBeanMapper.java:149)
    at net.sf.dozer.util.mapping.DozerBeanMapper.getMappingProcessor(DozerBeanMapper.java:132)
    at net.sf.dozer.util.mapping.DozerBeanMapper.map(DozerBeanMapper.java:94)
How can i map this so that it works?
我如何映射它以使其正常工作?
回答by Karthik
This works for me. I am using 5.2.1 version
这对我有用。我使用的是 5.2.1 版本
 <mapping wildcard="true" >
      <class-a>initRequest</class-a>
      <class-b>initResponse</class-b>   
      <field>
        <a>details</a>
        <b is-accessible="true">detObj.details</b>
      </field>
    </mapping>
Note that "is-accessable" is not required for . Hope it helps
请注意, . 希望能帮助到你
回答by user363900
Problem solved...
问题解决了...
is-accesible allows an object to be updated regardless of access modifier and presence of getters/setters (essential for objects generated using JAXB)
"dot" notation for deep mapping works to access nested objects
is-accesible 允许更新对象,而不管访问修饰符和 getter/setter 是否存在(对于使用 JAXB 生成的对象至关重要)
深度映射的“点”符号可用于访问嵌套对象
Combining the two is a feature that does not work in Dozer (maybe it does in a newer version)
将两者结合起来是一个在 Dozer 中不起作用的功能(也许它在较新的版本中起作用)
solution... modify the xsd such that the deep mapping is not required. This is not my ideal solution but its better than writing a custom converter for every object
解决方案...修改 xsd 以便不需要深度映射。这不是我理想的解决方案,但它比为每个对象编写自定义转换器更好
回答by Aneesh
In case of JaxB, use can download and use the plugin for generating the setters. Refer to this link for more details, https://jaxb2-commons.dev.java.net/collection-setter-injector/
对于JaxB,用户可以下载并使用插件生成setter。有关更多详细信息,请参阅此链接,https://jaxb2-commons.dev.java.net/collection-setter-injector/
回答by Michael Zilbermann
I would guess that accessors (getter / setter) are missing. By the way I think that you'll also need to provide an empty constructor for DetailsObject so dozer can instanciate it.
我猜想缺少访问器(getter / setter)。顺便说一句,我认为您还需要为 DetailsObject 提供一个空的构造函数,以便推土机可以实例化它。
回答by ManjuKn
<b is-accessible="true">detObj.details</b>
Should be replaced with
应该换成
<b is-accessible="true">DetailsObject.details</b>
回答by user2161559
While it does seem you cannnot use the "is-accessible" and dot notation together another approach is to break your deep mapping into smaller mappings.
虽然看起来你不能同时使用“is-accessible”和点符号,但另一种方法是将你的深度映射分解成更小的映射。
We ran into this situation with JAX-WS generated code. You have lists that have no setter methods and in our case were deeply nested. We found our solution by simply breaking the large deep mapping into smaller mappings that "walked" our way to what we wanted. I tried to explain this in my blog here:
我们使用 JAX-WS 生成的代码遇到了这种情况。你有没有 setter 方法的列表,在我们的例子中是深度嵌套的。我们通过简单地将大型深度映射分解为更小的映射来找到我们的解决方案,这些映射“走”了我们想要的道路。我试图在我的博客中解释这一点:
http://btarlton.blogspot.com/2014/08/dozer-deep-nestinga-different-approach.html
http://btarlton.blogspot.com/2014/08/dozer-deep-nestinga-different-approach.html
But the trick is just walking the object tree by smaller mappings and using is-accessible="true" when necessary to access the list with no setter and using "this" as the property name to keep passing the source along.
但诀窍只是通过较小的映射遍历对象树,并在需要时使用 is-accessible="true" 来访问没有 setter 的列表,并使用“this”作为属性名称来继续传递源。
Hope this helps!
希望这可以帮助!
回答by Superaghu
To summarize there are following options for this issue 1) Use JaxB pluggin to enable setters as discussed by Naveen 2) Use is-accessible for such properties
总而言之,此问题有以下选项 1) 使用 JaxB 插件来启用 Naveen 讨论的 setter 2) 对此类属性使用 is-accessible
I believe using first approach unnecessarily exposes setters for collections/lists as you can risk of setting them with null.
我相信使用第一种方法会不必要地暴露集合/列表的设置器,因为您可能会冒着将它们设置为 null 的风险。
We decided to enable is-accessible for such fields (and not to entire class) to avoid any side effects.
我们决定为这些字段(而不是整个类)启用 is-accessible 以避免任何副作用。
I have discussed the solution at Dozer Mapping Class level is-accessible
我已经讨论了Dozer Mapping Class level is-accessible的解决方案

