2015-07-21 27 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); 

我希望這將會有用。