首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >自定义DozerConverter仅在SpringBoot测试中调用。

自定义DozerConverter仅在SpringBoot测试中调用。
EN

Stack Overflow用户
提问于 2021-04-07 10:49:18
回答 2查看 284关注 0票数 1

我面临的问题是,我有一个带有自定义DozerConverter的Spring应用程序,该应用程序只在一个@SpringBootTest类中被DozerBeanMapper调用,而不是在服务类中调用。

如何定义DozerBeanMapper

DozerBeanMapper在配置类中定义,如下所示:

代码语言:javascript
运行
复制
@Configuration
public class Config {

    @Bean
    public Mapper getMapper() {

        DozerBeanMapper mapper = new DozerBeanMapper();
        mapper.setMappingFiles(Collections.singletonList("mappings.xml"));

        return mapper;
    }

}

我是mappings.xml

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
      http://dozer.sourceforge.net/schema/beanmapping.xsd">

    <configuration>
        <custom-converters>
            <converter type="com.app.util.converter.EntityToDtoDozerConverter">
                <class-a>com.app.model.entity.Entity</class-a>
                <class-b>com.app.model.dto.Dto</class-b>
            </converter>
        <custom-converters>
    </configuration>

</mappings>

这是定制的DozerConverter

代码语言:javascript
运行
复制
@Component
public class EntityToDtoDozerConverter extends DozerConverter<Entity, Dto> {

    private AnotherService myService;

    public EntityToDtoDozerConverter() {
        super(Entity.class, Dto.class);
    }

    public EntityToDtoDozerConverter(AnotherService myService) {
        this();
        this.myService = myService;
    }

    @Override
    public Dto convertTo(Entity entity, Dto dto) {

        if (dto == null)
            dto = new Dto();

        dto.setId(entity.getId());
        dto.setSubEntity(myService.findById(entity.getSubEntityId()));

        return dto;
    }

    @Override
    public Entity convertFrom(Dto dto, Entity entity) {

        if (entity == null)
            entity = new Entity();

        entity.setId(dto.getId());
        entity.setSubEntityId(dto.getSubEntity().getId());

        return entity;
    }
}

测试类(在它工作的地方)

这里,mapper.map()像我所期望的那样调用自定义转换器。

代码语言:javascript
运行
复制
@SpringBootTest
public class DozerTests {

    @Autowired
    Mapper mapper;

    @Test
    void myTest() {

        Entity entity = new Entity(1, 2);

        Dto dto = mapper.map(entity, Dto.class);    // -----> Here the dto is correct

        ...
    }
}

服务类(不工作的地方)

在这里,mapper.map()不调用我的自定义转换器,因此SubEntity会产生空值。

代码语言:javascript
运行
复制
@Service
public class Service implements IService {

    private final Mapper mapper;
    private final EntityManager em;
    ...

    public Service(Mapper mapper, EntityManager em) {
        this.mapper = mapper;
        this.em = em;
    }

    @Override
    public Dto findById(int id) {

        Entity entity = repository.findById(id).orElseThrow(() -> new EntityNotFoundException("not found"));

        Dto dto = mapper.map(entity, Dto.class);    // ------> Here the dto is incorrect (null value for SubEntity)

        return dto;
    }


}

更新:更深入地调试每一种情况,我发现导致不同行为的原因是Dozer的内部缓存机制。具体来说,当试图在"service类“情况下映射时,我可以看到映射程序内部有一些缓存映射,这些映射阻止他加载自定义转换器。在测试类中进行映射时,情况并非如此。

EN

Stack Overflow用户

发布于 2021-04-08 06:59:21

看上去是个未解决的老虫子。不使用注入自定义转换器

将自定义转换器添加到mapping.xml似乎使用(默认)构造的实例带有Spring依赖注入的自定义转换器

但是,您应该会看到一个错误,因为您的转换器中缺少AnotherService

但不知道为什么它能在你的考试课上工作。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66984545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档