gpt4 book ai didi

java - map 泛型类型和代理的推土机问题

转载 作者:行者123 更新时间:2023-12-01 11:18:21 25 4
gpt4 key购买 nike

在我们公司,我们发现 Dozer 在将字段从 hibernate 实体复制到简单的 DTO(简单的 POJO)时遇到问题,其中字段是其他实体的映射。它看起来是这样的:

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

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

Soo,Dozer,在尝试将字段从实体复制到 DTO 时尝试以某种方式复制代理而不是其内容,从而引发 LazyInitializationException(即使获取类型是 EAGER)。我们发现,我们可以创建一个包装器和一个处理这种情况的自定义转换器:

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();
}
}
}

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

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

到目前为止一切顺利。 那么问题是什么?问题出在另一种映射方式上——从 DTO 到实体。它不是从 MyDto 复制到 MyJPAEntity 条目到实体中(将内部 DTO 映射到内部实体),而是实际上将包含条目的映射复制到 MyJPAEntity 中 - 可能它无法猜测目标类型是什么,而不是映射对象,它只是复制它们。

所以我也能够通过指定 map 类型的提示来解决这个问题:

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

我可能已经帮助了一些人;)并且很高兴我解决了我的问题。

直到我必须使用剂量器将值从一个实体复制到另一个实体。现在,如果我使用提示,我会得到 LazyInitException,如果我使用上面的包装转换器,则映射器会忽略提示。Dozer 的 sourceforge 文档现在无法访问。有谁知道如何使用映射器并强制它使用我的提示?或者如何通过映射构建器正确配置它?

我想说,MaybePersistentMapToHashMapConverter 中使用的映射器实际上不知道它应该使用提示,因为它不知道它实际上正在映射名称为“map”的字段

最佳答案

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

您的 LazyInitializationException 可能是在推土机的 map 方法中调用 .class 。这是因为推土机将实例化新实体并​​填充它,并且该实体不在当前 session 中。我们更改了推土机 map 方法调用:

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);

我希望这会有用。

关于java - map 泛型类型和代理的推土机问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31533011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com