spring-boot - Orika Mapper-MapperFacade初始化后无法注册转换器

标签 spring-boot java-8 mapping orika

我创建了一个类,用于在 Spring 启动应用程序中使用Orika Mapper API复制bean属性,如下所示:

public class ObjectMapper {

    private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

    public static ClientEntity toClientEntity(ClientDTO clientDTO) {
        BoundMapperFacade<ClientDTO, ClientEntity> boundMapper = mapperFactory.getMapperFacade(ClientDTO.class, ClientEntity.class);
        return boundMapper.map(clientDTO);
    }   

    public static UserEntity toUserEntity(UserDTO userDTO) {
        mapperFactory.getConverterFactory().registerConverter(new PassThroughConverter(LocalDate.class));
        mapperFactory.getConverterFactory().registerConverter(new PassThroughConverter(LocalTime.class));
        BoundMapperFacade<UserDTO, UserEntity> boundMapper = mapperFactory.getMapperFacade(UserDTO.class, UserEntity.class);
        return boundMapper.map(userDTO);
    }
}

UserEntity和UserDTO POJO类具有JAVA 8 LocalDate和LocalTime属性,因此具有针对mapperFactory的registeredConverters。第一次可以正常工作,但在连续调用时会抛出以下异常:
java.lang.IllegalStateException: Cannot register converters after MapperFacade has been initialized
    at ma.glasnost.orika.converter.DefaultConverterFactory.registerConverter(DefaultConverterFactory.java:192) ~[orika-core-1.4.6.jar:na]
    at ma.glasnost.orika.impl.DefaultMapperFactory$ConverterFactoryFacade.registerConverter(DefaultMapperFactory.java:1614) ~[orika-core-1.4.6.jar:na]

我了解这是因为在初始化MapperFacade之后正在注册转换器。如何解决这个问题?初始化前如何注册转换器?

最佳答案

在提供的代码段中,您每次尝试调用toUserEntity()时都尝试注册转换器。因此,第一个调用将起作用,但是第二个调用将失败,因为MapperFacade在第一个调用期间已被初始化。

您可以像这样将转换器注册从映射方法移动到静态块:

private static MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
static {
    mapperFactory.getConverterFactory().registerConverter(new PassThroughConverter(LocalDate.class));
    mapperFactory.getConverterFactory().registerConverter(new PassThroughConverter(LocalTime.class));
}

另外,您可能希望将BoundMapperFacade移到静态字段,以避免不必要的getMapperFacade调用,如下所示:
private static BoundMapperFacade<ClientDTO, ClientEntity> clientBoundMapper 
                     = mapperFactory.getMapperFacade(ClientDTO.class, ClientEntity.class);
private static BoundMapperFacade<UserDTO, UserEntity> userBoundMapper 
                     = mapperFactory.getMapperFacade(UserDTO.class, UserEntity.class);

因此,映射方法将变成简单的一列式:
public static ClientEntity toClientEntity(ClientDTO clientDTO) {
    return clientBoundMapper.map(clientDTO);
}   

public static UserEntity toUserEntity(UserDTO userDTO) {
    return userBoundMapper.map(userDTO);
}

关于spring-boot - Orika Mapper-MapperFacade初始化后无法注册转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49725000/

相关文章:

java - 如何以最少的查询次数获取所有多对多关系?

java - 如何使用字符串流扩展(解析)路径

java - 计算 Map 中具有 Set as 值的项目

java - 将 HashMap 的键和值连接到列表

python - 将字典映射到数据框无法正常工作

java - 递归映射时的 MapStruct 问题

java - 从 JSON 映射到具有不同结构的 java 对象

java - Spring Boot Rest Api 在 N 个并行保存请求后卡住了

java - 为什么要加载WebMvcConfigurer?

java - 何时在 Spring Boot 中使用自定义上下文路径而不是根上下文