有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

我如何定义DozerBeanMapper

DozerBeanMapper是在如下配置类中定义的:

@Configuration
public class Config {

    @Bean
    public Mapper getMapper() {

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

        return mapper;
    }

}

这是mappings.xml

<?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>

这就是习惯{}:

@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()像我预期的那样调用自定义转换器

@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()不调用我的自定义转换器,所以子实体的结果是空值

@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;
    }


}

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


共 (0) 个答案