2015-07-21 39 views
0

在我们公司,我们发现,推土机在将字段从休眠实体复制到带有字段的简单DTO(简单的POJO)方面存在问题,这些字段是其他实体的地图。 这是它的外观:推土机问题与地图通用类型和代理

class MyJPAEntity{ 
    @JPAMappings(FetchType.EAGER) 
    Map<Integer, EmbeddableJPAEntity> map; 
} 

class MyDto{ 
    Map<Integer, MyOtherDto> map; 
} 

洙,推土机,试图DTO试图以某种方式复制代理而不是其内容,从而提高LazyInitializationException中(即使提取类型是到田间地头,从实体复制时急于)。我们想通了,我们可以创建一个包装,以及与交易情况的自定义转换器:

public class MaybePersistentMapToHashMapConverter extends 
    DozerConverter<Map, Map> implements MapperAware { 

    public static class Wrapper { 
     private Map map; 

     public Wrapper() { 
     } 

     public Wrapper(Map map) { 
      this.map = map; 
     } 

     public Map getMap() { 
      return map; 
     } 

     public void setMap(Map map) { 
      this.map = map; 
     } 
    } 

    private Mapper mapper; 

    public MaybePersistentMapToHashMapConverter() { 
     super(Map.class, Map.class); 
    } 

    @Override 
    public void setMapper(Mapper mapper) { 
     this.mapper = mapper; 
    } 

    @Override 
    public Map convertTo(Map source, Map destination) { 
     return map(source, destination); 
    } 

    @Override 
    public Map convertFrom(Map source, Map destination) { 
     return map(source, destination); 
    } 

    private Map map(Map source, Map destination) { 
     Wrapper wrapper; 

     if (source instanceof PersistentMap) { 
      wrapper = new Wrapper(new HashMap<>(source)); 
     } else { 
      wrapper = new Wrapper(source); 
     } 

     if (destination == null) { 
      Wrapper map = mapper.map(wrapper, Wrapper.class); 
      return map.map; 
     } else { 
      throw new UnsupportedOperationException(); 
     } 
    } 
} 

所以这个东西,只是包装地图,使推土机不会复制proxyMap。我只是在代码中配置一个映射:

mapping(fromType, toType, oneWay()) 
      .fields("map", "map", FieldsMappingOptions.customConverter(MaybePersistentMapToHashMapConverter.class) 

到目前为止这么好。 那么问题是什么?问题是与其他方式映射 - 从DTO到实体。不是从MyDto复制到MyJPAEntity条目到实体(将内部DTO映射到内部实体,而是实际上将包含条目的映射复制到MyJPAEntity中 - 可能无法猜测目标类型是什么,而不是映射对象,它只是。将它们复制

所以我能够解决的问题,以及,通过指定地图类型的提示:

fields("map", "map", FieldsMappingOptions.hintA(MyOtherDto.class), FieldsMappingOptions.hintB(EmbeddableJPAEntity.class)) 

我可能帮助一些人媒体链接)和很高兴,我解决我的问题。

直到我必须使用加料器将实体中的值复制到另一个实体。现在,如果我使用提示,我得到LazyInitException,如果我使用上面的换行转换器,则提示被映射器忽略。 Dozer的sourceforge文档现在无法访问。 有没有人有一个想法如何使用映射器,并强制它使用我的提示?或者如何通过映射生成器来正确配置它?

我要说的是,在MaybePersistentMapToHashMapConverter使用的映射其实就是不知道它应该使用的提示,因为它是不知道它实际上是映射名称的字段“地图”

回答

1

在我们的项目中,我们解决了这个问题,并严重陷入与您的问题完全相同的问题;)。

您的LazyInitializationException可能是用于在推土机的地图方法中调用.class。这是因为推土机将实例化新的实体并填充它,并且该实体不在当前会话中。 我们改变推土机地图方法调用来自:

A_Entity newEntity = dozer.map(dto,A_Entity.class); 

到:

A_Entity newEntity = new A_Entity(); 
dozer.map(A_dto,newEntity); 

和其他方式:

A_dto dto = dozer.map(entity,A_DTO.class); 

到:

A_dto dto = Spring.context.getBean("a_dto"); 
dozer.map(entity,dto); 

我希望这将会有用。